Merge branch 'master' into new-shortcut
This commit is contained in:
commit
728aca7703
217 changed files with 21240 additions and 14543 deletions
|
@ -8,8 +8,17 @@ ccache -s
|
||||||
|
|
||||||
BUILD_FLAVOR=mainline
|
BUILD_FLAVOR=mainline
|
||||||
|
|
||||||
|
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
||||||
|
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
|
||||||
|
base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
cd src/android
|
cd src/android
|
||||||
chmod +x ./gradlew
|
chmod +x ./gradlew
|
||||||
./gradlew "assemble${BUILD_FLAVOR}Release" "bundle${BUILD_FLAVOR}Release"
|
./gradlew "assemble${BUILD_FLAVOR}Release" "bundle${BUILD_FLAVOR}Release"
|
||||||
|
|
||||||
ccache -s
|
ccache -s
|
||||||
|
|
||||||
|
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
||||||
|
rm "${ANDROID_KEYSTORE_FILE}"
|
||||||
|
fi
|
||||||
|
|
|
@ -13,15 +13,3 @@ cp src/android/app/build/outputs/apk/"${BUILD_FLAVOR}/release/app-${BUILD_FLAVOR
|
||||||
"artifacts/${REV_NAME}.apk"
|
"artifacts/${REV_NAME}.apk"
|
||||||
cp src/android/app/build/outputs/bundle/"${BUILD_FLAVOR}Release"/"app-${BUILD_FLAVOR}-release.aab" \
|
cp src/android/app/build/outputs/bundle/"${BUILD_FLAVOR}Release"/"app-${BUILD_FLAVOR}-release.aab" \
|
||||||
"artifacts/${REV_NAME}.aab"
|
"artifacts/${REV_NAME}.aab"
|
||||||
|
|
||||||
if [ -n "${ANDROID_KEYSTORE_B64}" ]
|
|
||||||
then
|
|
||||||
echo "Signing apk..."
|
|
||||||
base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > ks.jks
|
|
||||||
|
|
||||||
apksigner sign --ks ks.jks \
|
|
||||||
--ks-key-alias "${ANDROID_KEY_ALIAS}" \
|
|
||||||
--ks-pass env:ANDROID_KEYSTORE_PASS "artifacts/${REV_NAME}.apk"
|
|
||||||
else
|
|
||||||
echo "No keystore specified, not signing the APK files."
|
|
||||||
fi
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ cmake .. \
|
||||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||||
-DENABLE_QT_TRANSLATION=ON \
|
-DENABLE_QT_TRANSLATION=ON \
|
||||||
-DUSE_DISCORD_PRESENCE=ON \
|
-DUSE_DISCORD_PRESENCE=ON \
|
||||||
|
-DYUZU_CRASH_DUMPS=ON \
|
||||||
-DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
|
-DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
|
||||||
-DYUZU_USE_BUNDLED_FFMPEG=ON \
|
-DYUZU_USE_BUNDLED_FFMPEG=ON \
|
||||||
-GNinja
|
-GNinja
|
||||||
|
|
|
@ -23,6 +23,7 @@ cmake .. \
|
||||||
-DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
|
-DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
|
||||||
-DYUZU_USE_BUNDLED_FFMPEG=ON \
|
-DYUZU_USE_BUNDLED_FFMPEG=ON \
|
||||||
-DYUZU_ENABLE_LTO=ON \
|
-DYUZU_ENABLE_LTO=ON \
|
||||||
|
-DYUZU_CRASH_DUMPS=ON \
|
||||||
-GNinja
|
-GNinja
|
||||||
|
|
||||||
ninja
|
ninja
|
||||||
|
|
|
@ -17,7 +17,6 @@ cmake .. \
|
||||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||||
-DENABLE_QT_TRANSLATION=ON \
|
-DENABLE_QT_TRANSLATION=ON \
|
||||||
-DUSE_CCACHE=ON \
|
-DUSE_CCACHE=ON \
|
||||||
-DYUZU_CRASH_DUMPS=ON \
|
|
||||||
-DYUZU_USE_BUNDLED_SDL2=OFF \
|
-DYUZU_USE_BUNDLED_SDL2=OFF \
|
||||||
-DYUZU_USE_EXTERNAL_SDL2=OFF \
|
-DYUZU_USE_EXTERNAL_SDL2=OFF \
|
||||||
-DYUZU_TESTS=OFF \
|
-DYUZU_TESTS=OFF \
|
||||||
|
|
5
.gitmodules
vendored
5
.gitmodules
vendored
|
@ -32,7 +32,7 @@
|
||||||
path = externals/xbyak
|
path = externals/xbyak
|
||||||
url = https://github.com/herumi/xbyak.git
|
url = https://github.com/herumi/xbyak.git
|
||||||
[submodule "opus"]
|
[submodule "opus"]
|
||||||
path = externals/opus/opus
|
path = externals/opus
|
||||||
url = https://github.com/xiph/opus.git
|
url = https://github.com/xiph/opus.git
|
||||||
[submodule "SDL"]
|
[submodule "SDL"]
|
||||||
path = externals/SDL
|
path = externals/SDL
|
||||||
|
@ -58,3 +58,6 @@
|
||||||
[submodule "VulkanMemoryAllocator"]
|
[submodule "VulkanMemoryAllocator"]
|
||||||
path = externals/VulkanMemoryAllocator
|
path = externals/VulkanMemoryAllocator
|
||||||
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
||||||
|
[submodule "breakpad"]
|
||||||
|
path = externals/breakpad
|
||||||
|
url = https://github.com/yuzu-emu/breakpad.git
|
||||||
|
|
|
@ -52,7 +52,7 @@ option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android"
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(YUZU_ROOM "Compile LDN room server" ON "NOT ANDROID" OFF)
|
CMAKE_DEPENDENT_OPTION(YUZU_ROOM "Compile LDN room server" ON "NOT ANDROID" OFF)
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(YUZU_CRASH_DUMPS "Compile Windows crash dump (Minidump) support" OFF "WIN32" OFF)
|
CMAKE_DEPENDENT_OPTION(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF)
|
||||||
|
|
||||||
option(YUZU_USE_BUNDLED_VCPKG "Use vcpkg for yuzu dependencies" "${MSVC}")
|
option(YUZU_USE_BUNDLED_VCPKG "Use vcpkg for yuzu dependencies" "${MSVC}")
|
||||||
|
|
||||||
|
@ -139,9 +139,6 @@ if (YUZU_USE_BUNDLED_VCPKG)
|
||||||
if (YUZU_TESTS)
|
if (YUZU_TESTS)
|
||||||
list(APPEND VCPKG_MANIFEST_FEATURES "yuzu-tests")
|
list(APPEND VCPKG_MANIFEST_FEATURES "yuzu-tests")
|
||||||
endif()
|
endif()
|
||||||
if (YUZU_CRASH_DUMPS)
|
|
||||||
list(APPEND VCPKG_MANIFEST_FEATURES "dbghelp")
|
|
||||||
endif()
|
|
||||||
if (ENABLE_WEB_SERVICE)
|
if (ENABLE_WEB_SERVICE)
|
||||||
list(APPEND VCPKG_MANIFEST_FEATURES "web-service")
|
list(APPEND VCPKG_MANIFEST_FEATURES "web-service")
|
||||||
endif()
|
endif()
|
||||||
|
@ -551,6 +548,18 @@ if (NOT YUZU_USE_BUNDLED_FFMPEG)
|
||||||
find_package(FFmpeg 4.3 REQUIRED QUIET COMPONENTS ${FFmpeg_COMPONENTS})
|
find_package(FFmpeg 4.3 REQUIRED QUIET COMPONENTS ${FFmpeg_COMPONENTS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (WIN32 AND YUZU_CRASH_DUMPS)
|
||||||
|
set(BREAKPAD_VER "breakpad-c89f9dd")
|
||||||
|
download_bundled_external("breakpad/" ${BREAKPAD_VER} BREAKPAD_PREFIX)
|
||||||
|
|
||||||
|
set(BREAKPAD_CLIENT_INCLUDE_DIR "${BREAKPAD_PREFIX}/include")
|
||||||
|
set(BREAKPAD_CLIENT_LIBRARY "${BREAKPAD_PREFIX}/lib/libbreakpad_client.lib")
|
||||||
|
|
||||||
|
add_library(libbreakpad_client INTERFACE IMPORTED)
|
||||||
|
target_link_libraries(libbreakpad_client INTERFACE "${BREAKPAD_CLIENT_LIBRARY}")
|
||||||
|
target_include_directories(libbreakpad_client INTERFACE "${BREAKPAD_CLIENT_INCLUDE_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Prefer the -pthread flag on Linux.
|
# Prefer the -pthread flag on Linux.
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
@ -570,13 +579,6 @@ elseif (WIN32)
|
||||||
# PSAPI is the Process Status API
|
# PSAPI is the Process Status API
|
||||||
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version)
|
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (YUZU_CRASH_DUMPS)
|
|
||||||
find_library(DBGHELP_LIBRARY dbghelp)
|
|
||||||
if ("${DBGHELP_LIBRARY}" STREQUAL "DBGHELP_LIBRARY-NOTFOUND")
|
|
||||||
message(FATAL_ERROR "YUZU_CRASH_DUMPS enabled but dbghelp library not found")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
elseif (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$")
|
elseif (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$")
|
||||||
set(PLATFORM_LIBRARIES rt)
|
set(PLATFORM_LIBRARIES rt)
|
||||||
endif()
|
endif()
|
||||||
|
|
1695
dist/languages/ar.ts
vendored
1695
dist/languages/ar.ts
vendored
File diff suppressed because it is too large
Load diff
848
dist/languages/ca.ts
vendored
848
dist/languages/ca.ts
vendored
File diff suppressed because it is too large
Load diff
856
dist/languages/cs.ts
vendored
856
dist/languages/cs.ts
vendored
File diff suppressed because it is too large
Load diff
856
dist/languages/da.ts
vendored
856
dist/languages/da.ts
vendored
File diff suppressed because it is too large
Load diff
997
dist/languages/de.ts
vendored
997
dist/languages/de.ts
vendored
File diff suppressed because it is too large
Load diff
856
dist/languages/el.ts
vendored
856
dist/languages/el.ts
vendored
File diff suppressed because it is too large
Load diff
890
dist/languages/es.ts
vendored
890
dist/languages/es.ts
vendored
File diff suppressed because it is too large
Load diff
874
dist/languages/fr.ts
vendored
874
dist/languages/fr.ts
vendored
File diff suppressed because it is too large
Load diff
1685
dist/languages/hu.ts
vendored
1685
dist/languages/hu.ts
vendored
File diff suppressed because it is too large
Load diff
856
dist/languages/id.ts
vendored
856
dist/languages/id.ts
vendored
File diff suppressed because it is too large
Load diff
864
dist/languages/it.ts
vendored
864
dist/languages/it.ts
vendored
File diff suppressed because it is too large
Load diff
928
dist/languages/ja_JP.ts
vendored
928
dist/languages/ja_JP.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/ko_KR.ts
vendored
850
dist/languages/ko_KR.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/nb.ts
vendored
850
dist/languages/nb.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/nl.ts
vendored
850
dist/languages/nl.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/pl.ts
vendored
850
dist/languages/pl.ts
vendored
File diff suppressed because it is too large
Load diff
886
dist/languages/pt_BR.ts
vendored
886
dist/languages/pt_BR.ts
vendored
File diff suppressed because it is too large
Load diff
884
dist/languages/pt_PT.ts
vendored
884
dist/languages/pt_PT.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/ru_RU.ts
vendored
850
dist/languages/ru_RU.ts
vendored
File diff suppressed because it is too large
Load diff
856
dist/languages/sv.ts
vendored
856
dist/languages/sv.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/tr_TR.ts
vendored
850
dist/languages/tr_TR.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/uk.ts
vendored
850
dist/languages/uk.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/vi.ts
vendored
850
dist/languages/vi.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/vi_VN.ts
vendored
850
dist/languages/vi_VN.ts
vendored
File diff suppressed because it is too large
Load diff
866
dist/languages/zh_CN.ts
vendored
866
dist/languages/zh_CN.ts
vendored
File diff suppressed because it is too large
Load diff
850
dist/languages/zh_TW.ts
vendored
850
dist/languages/zh_TW.ts
vendored
File diff suppressed because it is too large
Load diff
1
dist/org.yuzu_emu.yuzu.desktop
vendored
1
dist/org.yuzu_emu.yuzu.desktop
vendored
|
@ -13,3 +13,4 @@ Exec=yuzu %f
|
||||||
Categories=Game;Emulator;Qt;
|
Categories=Game;Emulator;Qt;
|
||||||
MimeType=application/x-nx-nro;application/x-nx-nso;application/x-nx-nsp;application/x-nx-xci;
|
MimeType=application/x-nx-nro;application/x-nx-nso;application/x-nx-nsp;application/x-nx-xci;
|
||||||
Keywords=Nintendo;Switch;
|
Keywords=Nintendo;Switch;
|
||||||
|
StartupWMClass=yuzu
|
||||||
|
|
106
externals/CMakeLists.txt
vendored
106
externals/CMakeLists.txt
vendored
|
@ -134,6 +134,10 @@ endif()
|
||||||
|
|
||||||
# Opus
|
# Opus
|
||||||
if (NOT TARGET Opus::opus)
|
if (NOT TARGET Opus::opus)
|
||||||
|
set(OPUS_BUILD_TESTING OFF)
|
||||||
|
set(OPUS_BUILD_PROGRAMS OFF)
|
||||||
|
set(OPUS_INSTALL_PKG_CONFIG_MODULE OFF)
|
||||||
|
set(OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF)
|
||||||
add_subdirectory(opus)
|
add_subdirectory(opus)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -189,3 +193,105 @@ if (ANDROID)
|
||||||
add_subdirectory(libadrenotools)
|
add_subdirectory(libadrenotools)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Breakpad
|
||||||
|
# https://github.com/microsoft/vcpkg/blob/master/ports/breakpad/CMakeLists.txt
|
||||||
|
if (YUZU_CRASH_DUMPS AND NOT TARGET libbreakpad_client)
|
||||||
|
set(BREAKPAD_WIN32_DEFINES
|
||||||
|
NOMINMAX
|
||||||
|
UNICODE
|
||||||
|
WIN32_LEAN_AND_MEAN
|
||||||
|
_CRT_SECURE_NO_WARNINGS
|
||||||
|
_CRT_SECURE_NO_DEPRECATE
|
||||||
|
_CRT_NONSTDC_NO_DEPRECATE
|
||||||
|
)
|
||||||
|
|
||||||
|
# libbreakpad
|
||||||
|
add_library(libbreakpad STATIC)
|
||||||
|
file(GLOB_RECURSE LIBBREAKPAD_SOURCES breakpad/src/processor/*.cc)
|
||||||
|
file(GLOB_RECURSE LIBDISASM_SOURCES breakpad/src/third_party/libdisasm/*.c)
|
||||||
|
list(FILTER LIBBREAKPAD_SOURCES EXCLUDE REGEX "_unittest|_selftest|synth_minidump|/tests|/testdata|/solaris|microdump_stackwalk|minidump_dump|minidump_stackwalk")
|
||||||
|
if (WIN32)
|
||||||
|
list(FILTER LIBBREAKPAD_SOURCES EXCLUDE REGEX "/linux|/mac|/android")
|
||||||
|
target_compile_definitions(libbreakpad PRIVATE ${BREAKPAD_WIN32_DEFINES})
|
||||||
|
target_include_directories(libbreakpad PRIVATE "${CMAKE_GENERATOR_INSTANCE}/DIA SDK/include")
|
||||||
|
elseif (APPLE)
|
||||||
|
list(FILTER LIBBREAKPAD_SOURCES EXCLUDE REGEX "/linux|/windows|/android")
|
||||||
|
else()
|
||||||
|
list(FILTER LIBBREAKPAD_SOURCES EXCLUDE REGEX "/mac|/windows|/android")
|
||||||
|
endif()
|
||||||
|
target_sources(libbreakpad PRIVATE ${LIBBREAKPAD_SOURCES} ${LIBDISASM_SOURCES})
|
||||||
|
target_include_directories(libbreakpad
|
||||||
|
PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/breakpad/src
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/breakpad/src/third_party/libdisasm
|
||||||
|
)
|
||||||
|
|
||||||
|
# libbreakpad_client
|
||||||
|
add_library(libbreakpad_client STATIC)
|
||||||
|
file(GLOB LIBBREAKPAD_COMMON_SOURCES breakpad/src/common/*.cc breakpad/src/common/*.c breakpad/src/client/*.cc)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
file(GLOB_RECURSE LIBBREAKPAD_CLIENT_SOURCES breakpad/src/client/windows/*.cc breakpad/src/common/windows/*.cc)
|
||||||
|
list(FILTER LIBBREAKPAD_COMMON_SOURCES EXCLUDE REGEX "language.cc|path_helper.cc|stabs_to_module.cc|stabs_reader.cc|minidump_file_writer.cc")
|
||||||
|
target_include_directories(libbreakpad_client PRIVATE "${CMAKE_GENERATOR_INSTANCE}/DIA SDK/include")
|
||||||
|
target_compile_definitions(libbreakpad_client PRIVATE ${BREAKPAD_WIN32_DEFINES})
|
||||||
|
elseif (APPLE)
|
||||||
|
target_compile_definitions(libbreakpad_client PRIVATE HAVE_MACH_O_NLIST_H)
|
||||||
|
file(GLOB_RECURSE LIBBREAKPAD_CLIENT_SOURCES breakpad/src/client/mac/*.cc breakpad/src/common/mac/*.cc)
|
||||||
|
list(APPEND LIBBREAKPAD_CLIENT_SOURCES breakpad/src/common/mac/MachIPC.mm)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(libbreakpad_client PUBLIC -DHAVE_A_OUT_H)
|
||||||
|
file(GLOB_RECURSE LIBBREAKPAD_CLIENT_SOURCES breakpad/src/client/linux/*.cc breakpad/src/common/linux/*.cc)
|
||||||
|
endif()
|
||||||
|
list(APPEND LIBBREAKPAD_CLIENT_SOURCES ${LIBBREAKPAD_COMMON_SOURCES})
|
||||||
|
list(FILTER LIBBREAKPAD_CLIENT_SOURCES EXCLUDE REGEX "/sender|/tests|/unittests|/testcases|_unittest|_test")
|
||||||
|
target_sources(libbreakpad_client PRIVATE ${LIBBREAKPAD_CLIENT_SOURCES})
|
||||||
|
target_include_directories(libbreakpad_client PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/breakpad/src)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
target_link_libraries(libbreakpad_client PRIVATE wininet.lib)
|
||||||
|
elseif (APPLE)
|
||||||
|
find_library(CoreFoundation_FRAMEWORK CoreFoundation)
|
||||||
|
target_link_libraries(libbreakpad_client PRIVATE ${CoreFoundation_FRAMEWORK})
|
||||||
|
else()
|
||||||
|
find_library(PTHREAD_LIBRARIES pthread)
|
||||||
|
target_compile_definitions(libbreakpad_client PRIVATE HAVE_GETCONTEXT=1)
|
||||||
|
if (PTHREAD_LIBRARIES)
|
||||||
|
target_link_libraries(libbreakpad_client PRIVATE ${PTHREAD_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Host tools for symbol processing
|
||||||
|
if (LINUX)
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
|
||||||
|
add_executable(minidump_stackwalk breakpad/src/processor/minidump_stackwalk.cc)
|
||||||
|
target_link_libraries(minidump_stackwalk PRIVATE libbreakpad libbreakpad_client)
|
||||||
|
|
||||||
|
add_executable(dump_syms
|
||||||
|
breakpad/src/common/dwarf_cfi_to_module.cc
|
||||||
|
breakpad/src/common/dwarf_cu_to_module.cc
|
||||||
|
breakpad/src/common/dwarf_line_to_module.cc
|
||||||
|
breakpad/src/common/dwarf_range_list_handler.cc
|
||||||
|
breakpad/src/common/language.cc
|
||||||
|
breakpad/src/common/module.cc
|
||||||
|
breakpad/src/common/path_helper.cc
|
||||||
|
breakpad/src/common/stabs_reader.cc
|
||||||
|
breakpad/src/common/stabs_to_module.cc
|
||||||
|
breakpad/src/common/dwarf/bytereader.cc
|
||||||
|
breakpad/src/common/dwarf/dwarf2diehandler.cc
|
||||||
|
breakpad/src/common/dwarf/dwarf2reader.cc
|
||||||
|
breakpad/src/common/dwarf/elf_reader.cc
|
||||||
|
breakpad/src/common/linux/crc32.cc
|
||||||
|
breakpad/src/common/linux/dump_symbols.cc
|
||||||
|
breakpad/src/common/linux/elf_symbols_to_module.cc
|
||||||
|
breakpad/src/common/linux/elfutils.cc
|
||||||
|
breakpad/src/common/linux/file_id.cc
|
||||||
|
breakpad/src/common/linux/linux_libc_support.cc
|
||||||
|
breakpad/src/common/linux/memory_mapped_file.cc
|
||||||
|
breakpad/src/common/linux/safe_readlink.cc
|
||||||
|
breakpad/src/tools/linux/dump_syms/dump_syms.cc)
|
||||||
|
target_link_libraries(dump_syms PRIVATE libbreakpad_client ZLIB::ZLIB)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
2
externals/SDL
vendored
2
externals/SDL
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 031912c4b6c5db80b443f04aa56fec3e4e645153
|
Subproject commit cc016b0046d563287f0aa9f09b958b5e70d43696
|
2
externals/Vulkan-Headers
vendored
2
externals/Vulkan-Headers
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit ed857118e243fdc0f3a100f00ac9919e874cfe63
|
Subproject commit df60f0316899460eeaaefa06d2dd7e4e300c1604
|
2
externals/VulkanMemoryAllocator
vendored
2
externals/VulkanMemoryAllocator
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 9b0fc3e7b02afe97895eb3e945fe800c3a7485ac
|
Subproject commit 2f382df218d7e8516dee3b3caccb819a62b571a2
|
1
externals/breakpad
vendored
Submodule
1
externals/breakpad
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit c89f9dddc793f19910ef06c13e4fd240da4e7a59
|
2
externals/cpp-httplib
vendored
2
externals/cpp-httplib
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 6d963fbe8d415399d65e94db7910bbd22fe3741c
|
Subproject commit a609330e4c6374f741d3b369269f7848255e1954
|
2
externals/cpp-jwt
vendored
2
externals/cpp-jwt
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit e12ef06218596b52d9b5d6e1639484866a8e7067
|
Subproject commit 10ef5735d842b31025f1257ae78899f50a40fb14
|
2
externals/dynarmic
vendored
2
externals/dynarmic
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 7da378033a7764f955516f75194856d87bbcd7a5
|
Subproject commit 0df09e2f6b61c2d7ad2f2053d4f020a5c33e0378
|
2
externals/ffmpeg/ffmpeg
vendored
2
externals/ffmpeg/ffmpeg
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 6b6b9e593dd4d3aaf75f48d40a13ef03bdef9fdb
|
Subproject commit 9c1294eaddb88cb0e044c675ccae059a85fc9c6c
|
2
externals/inih/inih
vendored
2
externals/inih/inih
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 1e80a47dffbda813604f0913e2ad68c7054c14e4
|
Subproject commit 9cecf0643da0846e77f64d10a126d9f48b9e05e8
|
7
externals/libusb/CMakeLists.txt
vendored
7
externals/libusb/CMakeLists.txt
vendored
|
@ -49,11 +49,6 @@ if (MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux") OR APPLE)
|
||||||
|
|
||||||
set(LIBUSB_INCLUDE_DIRS "${LIBUSB_SRC_DIR}/libusb" CACHE PATH "libusb headers path" FORCE)
|
set(LIBUSB_INCLUDE_DIRS "${LIBUSB_SRC_DIR}/libusb" CACHE PATH "libusb headers path" FORCE)
|
||||||
|
|
||||||
# MINGW: causes "externals/libusb/libusb/libusb/os/windows_winusb.c:1427:2: error: conversion to non-scalar type requested", so cannot statically link it for now.
|
|
||||||
if (NOT MINGW)
|
|
||||||
set(LIBUSB_CFLAGS "-DGUID_DEVINTERFACE_USB_DEVICE=\\(GUID\\){0xA5DCBF10,0x6530,0x11D2,{0x90,0x1F,0x00,0xC0,0x4F,0xB9,0x51,0xED}}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
make_directory("${LIBUSB_PREFIX}")
|
make_directory("${LIBUSB_PREFIX}")
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
@ -146,8 +141,6 @@ else() # MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
target_include_directories(usb BEFORE PRIVATE libusb/msvc)
|
target_include_directories(usb BEFORE PRIVATE libusb/msvc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Works around other libraries providing their own definition of USB GUIDs (e.g. SDL2)
|
|
||||||
target_compile_definitions(usb PRIVATE "-DGUID_DEVINTERFACE_USB_DEVICE=(GUID){ 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}}")
|
|
||||||
else()
|
else()
|
||||||
target_include_directories(usb
|
target_include_directories(usb
|
||||||
# turns out other projects also have "config.h", so make sure the
|
# turns out other projects also have "config.h", so make sure the
|
||||||
|
|
2
externals/libusb/libusb
vendored
2
externals/libusb/libusb
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit c6a35c56016ea2ab2f19115d2ea1e85e0edae155
|
Subproject commit c060e9ce30ac2e3ffb49d94209c4dae77b6642f7
|
1
externals/opus
vendored
Submodule
1
externals/opus
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 101a71e03bbf860aaafb7090a0e440675cb27660
|
259
externals/opus/CMakeLists.txt
vendored
259
externals/opus/CMakeLists.txt
vendored
|
@ -1,259 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: 2019 yuzu Emulator Project
|
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.8)
|
|
||||||
|
|
||||||
project(opus)
|
|
||||||
|
|
||||||
option(OPUS_STACK_PROTECTOR "Use stack protection" OFF)
|
|
||||||
option(OPUS_USE_ALLOCA "Use alloca for stack arrays (on non-C99 compilers)" OFF)
|
|
||||||
option(OPUS_CUSTOM_MODES "Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames" OFF)
|
|
||||||
option(OPUS_FIXED_POINT "Compile as fixed-point (for machines without a fast enough FPU)" OFF)
|
|
||||||
option(OPUS_ENABLE_FLOAT_API "Compile with the floating point API (for machines with float library" ON)
|
|
||||||
|
|
||||||
include(opus/opus_functions.cmake)
|
|
||||||
|
|
||||||
if(OPUS_STACK_PROTECTOR)
|
|
||||||
if(NOT MSVC) # GC on by default on MSVC
|
|
||||||
check_and_set_flag(STACK_PROTECTION_STRONG -fstack-protector-strong)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
if(MSVC)
|
|
||||||
check_and_set_flag(BUFFER_SECURITY_CHECK /GS-)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(opus
|
|
||||||
# CELT sources
|
|
||||||
opus/celt/bands.c
|
|
||||||
opus/celt/celt.c
|
|
||||||
opus/celt/celt_decoder.c
|
|
||||||
opus/celt/celt_encoder.c
|
|
||||||
opus/celt/celt_lpc.c
|
|
||||||
opus/celt/cwrs.c
|
|
||||||
opus/celt/entcode.c
|
|
||||||
opus/celt/entdec.c
|
|
||||||
opus/celt/entenc.c
|
|
||||||
opus/celt/kiss_fft.c
|
|
||||||
opus/celt/laplace.c
|
|
||||||
opus/celt/mathops.c
|
|
||||||
opus/celt/mdct.c
|
|
||||||
opus/celt/modes.c
|
|
||||||
opus/celt/pitch.c
|
|
||||||
opus/celt/quant_bands.c
|
|
||||||
opus/celt/rate.c
|
|
||||||
opus/celt/vq.c
|
|
||||||
|
|
||||||
# SILK sources
|
|
||||||
opus/silk/A2NLSF.c
|
|
||||||
opus/silk/CNG.c
|
|
||||||
opus/silk/HP_variable_cutoff.c
|
|
||||||
opus/silk/LPC_analysis_filter.c
|
|
||||||
opus/silk/LPC_fit.c
|
|
||||||
opus/silk/LPC_inv_pred_gain.c
|
|
||||||
opus/silk/LP_variable_cutoff.c
|
|
||||||
opus/silk/NLSF2A.c
|
|
||||||
opus/silk/NLSF_VQ.c
|
|
||||||
opus/silk/NLSF_VQ_weights_laroia.c
|
|
||||||
opus/silk/NLSF_decode.c
|
|
||||||
opus/silk/NLSF_del_dec_quant.c
|
|
||||||
opus/silk/NLSF_encode.c
|
|
||||||
opus/silk/NLSF_stabilize.c
|
|
||||||
opus/silk/NLSF_unpack.c
|
|
||||||
opus/silk/NSQ.c
|
|
||||||
opus/silk/NSQ_del_dec.c
|
|
||||||
opus/silk/PLC.c
|
|
||||||
opus/silk/VAD.c
|
|
||||||
opus/silk/VQ_WMat_EC.c
|
|
||||||
opus/silk/ana_filt_bank_1.c
|
|
||||||
opus/silk/biquad_alt.c
|
|
||||||
opus/silk/bwexpander.c
|
|
||||||
opus/silk/bwexpander_32.c
|
|
||||||
opus/silk/check_control_input.c
|
|
||||||
opus/silk/code_signs.c
|
|
||||||
opus/silk/control_SNR.c
|
|
||||||
opus/silk/control_audio_bandwidth.c
|
|
||||||
opus/silk/control_codec.c
|
|
||||||
opus/silk/dec_API.c
|
|
||||||
opus/silk/decode_core.c
|
|
||||||
opus/silk/decode_frame.c
|
|
||||||
opus/silk/decode_indices.c
|
|
||||||
opus/silk/decode_parameters.c
|
|
||||||
opus/silk/decode_pitch.c
|
|
||||||
opus/silk/decode_pulses.c
|
|
||||||
opus/silk/decoder_set_fs.c
|
|
||||||
opus/silk/enc_API.c
|
|
||||||
opus/silk/encode_indices.c
|
|
||||||
opus/silk/encode_pulses.c
|
|
||||||
opus/silk/gain_quant.c
|
|
||||||
opus/silk/init_decoder.c
|
|
||||||
opus/silk/init_encoder.c
|
|
||||||
opus/silk/inner_prod_aligned.c
|
|
||||||
opus/silk/interpolate.c
|
|
||||||
opus/silk/lin2log.c
|
|
||||||
opus/silk/log2lin.c
|
|
||||||
opus/silk/pitch_est_tables.c
|
|
||||||
opus/silk/process_NLSFs.c
|
|
||||||
opus/silk/quant_LTP_gains.c
|
|
||||||
opus/silk/resampler.c
|
|
||||||
opus/silk/resampler_down2.c
|
|
||||||
opus/silk/resampler_down2_3.c
|
|
||||||
opus/silk/resampler_private_AR2.c
|
|
||||||
opus/silk/resampler_private_IIR_FIR.c
|
|
||||||
opus/silk/resampler_private_down_FIR.c
|
|
||||||
opus/silk/resampler_private_up2_HQ.c
|
|
||||||
opus/silk/resampler_rom.c
|
|
||||||
opus/silk/shell_coder.c
|
|
||||||
opus/silk/sigm_Q15.c
|
|
||||||
opus/silk/sort.c
|
|
||||||
opus/silk/stereo_LR_to_MS.c
|
|
||||||
opus/silk/stereo_MS_to_LR.c
|
|
||||||
opus/silk/stereo_decode_pred.c
|
|
||||||
opus/silk/stereo_encode_pred.c
|
|
||||||
opus/silk/stereo_find_predictor.c
|
|
||||||
opus/silk/stereo_quant_pred.c
|
|
||||||
opus/silk/sum_sqr_shift.c
|
|
||||||
opus/silk/table_LSF_cos.c
|
|
||||||
opus/silk/tables_LTP.c
|
|
||||||
opus/silk/tables_NLSF_CB_NB_MB.c
|
|
||||||
opus/silk/tables_NLSF_CB_WB.c
|
|
||||||
opus/silk/tables_gain.c
|
|
||||||
opus/silk/tables_other.c
|
|
||||||
opus/silk/tables_pitch_lag.c
|
|
||||||
opus/silk/tables_pulses_per_block.c
|
|
||||||
|
|
||||||
# Opus sources
|
|
||||||
opus/src/analysis.c
|
|
||||||
opus/src/mapping_matrix.c
|
|
||||||
opus/src/mlp.c
|
|
||||||
opus/src/mlp_data.c
|
|
||||||
opus/src/opus.c
|
|
||||||
opus/src/opus_decoder.c
|
|
||||||
opus/src/opus_encoder.c
|
|
||||||
opus/src/opus_multistream.c
|
|
||||||
opus/src/opus_multistream_decoder.c
|
|
||||||
opus/src/opus_multistream_encoder.c
|
|
||||||
opus/src/opus_projection_decoder.c
|
|
||||||
opus/src/opus_projection_encoder.c
|
|
||||||
opus/src/repacketizer.c
|
|
||||||
)
|
|
||||||
|
|
||||||
if (DEBUG)
|
|
||||||
target_sources(opus PRIVATE opus/silk/debug.c)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (OPUS_FIXED_POINT)
|
|
||||||
target_sources(opus PRIVATE
|
|
||||||
opus/silk/fixed/LTP_analysis_filter_FIX.c
|
|
||||||
opus/silk/fixed/LTP_scale_ctrl_FIX.c
|
|
||||||
opus/silk/fixed/apply_sine_window_FIX.c
|
|
||||||
opus/silk/fixed/autocorr_FIX.c
|
|
||||||
opus/silk/fixed/burg_modified_FIX.c
|
|
||||||
opus/silk/fixed/corrMatrix_FIX.c
|
|
||||||
opus/silk/fixed/encode_frame_FIX.c
|
|
||||||
opus/silk/fixed/find_LPC_FIX.c
|
|
||||||
opus/silk/fixed/find_LTP_FIX.c
|
|
||||||
opus/silk/fixed/find_pitch_lags_FIX.c
|
|
||||||
opus/silk/fixed/find_pred_coefs_FIX.c
|
|
||||||
opus/silk/fixed/k2a_FIX.c
|
|
||||||
opus/silk/fixed/k2a_Q16_FIX.c
|
|
||||||
opus/silk/fixed/noise_shape_analysis_FIX.c
|
|
||||||
opus/silk/fixed/pitch_analysis_core_FIX.c
|
|
||||||
opus/silk/fixed/prefilter_FIX.c
|
|
||||||
opus/silk/fixed/process_gains_FIX.c
|
|
||||||
opus/silk/fixed/regularize_correlations_FIX.c
|
|
||||||
opus/silk/fixed/residual_energy16_FIX.c
|
|
||||||
opus/silk/fixed/residual_energy_FIX.c
|
|
||||||
opus/silk/fixed/schur64_FIX.c
|
|
||||||
opus/silk/fixed/schur_FIX.c
|
|
||||||
opus/silk/fixed/solve_LS_FIX.c
|
|
||||||
opus/silk/fixed/vector_ops_FIX.c
|
|
||||||
opus/silk/fixed/warped_autocorrelation_FIX.c
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
target_sources(opus PRIVATE
|
|
||||||
opus/silk/float/LPC_analysis_filter_FLP.c
|
|
||||||
opus/silk/float/LPC_inv_pred_gain_FLP.c
|
|
||||||
opus/silk/float/LTP_analysis_filter_FLP.c
|
|
||||||
opus/silk/float/LTP_scale_ctrl_FLP.c
|
|
||||||
opus/silk/float/apply_sine_window_FLP.c
|
|
||||||
opus/silk/float/autocorrelation_FLP.c
|
|
||||||
opus/silk/float/burg_modified_FLP.c
|
|
||||||
opus/silk/float/bwexpander_FLP.c
|
|
||||||
opus/silk/float/corrMatrix_FLP.c
|
|
||||||
opus/silk/float/encode_frame_FLP.c
|
|
||||||
opus/silk/float/energy_FLP.c
|
|
||||||
opus/silk/float/find_LPC_FLP.c
|
|
||||||
opus/silk/float/find_LTP_FLP.c
|
|
||||||
opus/silk/float/find_pitch_lags_FLP.c
|
|
||||||
opus/silk/float/find_pred_coefs_FLP.c
|
|
||||||
opus/silk/float/inner_product_FLP.c
|
|
||||||
opus/silk/float/k2a_FLP.c
|
|
||||||
opus/silk/float/noise_shape_analysis_FLP.c
|
|
||||||
opus/silk/float/pitch_analysis_core_FLP.c
|
|
||||||
opus/silk/float/process_gains_FLP.c
|
|
||||||
opus/silk/float/regularize_correlations_FLP.c
|
|
||||||
opus/silk/float/residual_energy_FLP.c
|
|
||||||
opus/silk/float/scale_copy_vector_FLP.c
|
|
||||||
opus/silk/float/scale_vector_FLP.c
|
|
||||||
opus/silk/float/schur_FLP.c
|
|
||||||
opus/silk/float/sort_FLP.c
|
|
||||||
opus/silk/float/warped_autocorrelation_FLP.c
|
|
||||||
opus/silk/float/wrappers_FLP.c
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_compile_definitions(opus PRIVATE OPUS_BUILD ENABLE_HARDENING)
|
|
||||||
|
|
||||||
if(NOT MSVC)
|
|
||||||
if(MINGW)
|
|
||||||
target_compile_definitions(opus PRIVATE _FORTIFY_SOURCE=0)
|
|
||||||
else()
|
|
||||||
target_compile_definitions(opus PRIVATE _FORTIFY_SOURCE=2)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# It is strongly recommended to uncomment one of these VAR_ARRAYS: Use C99
|
|
||||||
# variable-length arrays for stack allocation USE_ALLOCA: Use alloca() for stack
|
|
||||||
# allocation If none is defined, then the fallback is a non-threadsafe global
|
|
||||||
# array
|
|
||||||
if(OPUS_USE_ALLOCA OR MSVC)
|
|
||||||
target_compile_definitions(opus PRIVATE USE_ALLOCA)
|
|
||||||
else()
|
|
||||||
target_compile_definitions(opus PRIVATE VAR_ARRAYS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(OPUS_CUSTOM_MODES)
|
|
||||||
target_compile_definitions(opus PRIVATE CUSTOM_MODES)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT OPUS_ENABLE_FLOAT_API)
|
|
||||||
target_compile_definitions(opus PRIVATE DISABLE_FLOAT_API)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_compile_definitions(opus
|
|
||||||
PUBLIC
|
|
||||||
-DOPUS_VERSION="\\"1.3.1\\""
|
|
||||||
|
|
||||||
PRIVATE
|
|
||||||
# Use C99 intrinsics to speed up float-to-int conversion
|
|
||||||
HAVE_LRINTF
|
|
||||||
)
|
|
||||||
|
|
||||||
if (FIXED_POINT)
|
|
||||||
target_compile_definitions(opus PRIVATE -DFIXED_POINT=1 -DDISABLE_FLOAT_API)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(opus
|
|
||||||
PUBLIC
|
|
||||||
opus/include
|
|
||||||
|
|
||||||
PRIVATE
|
|
||||||
opus/celt
|
|
||||||
opus/silk
|
|
||||||
opus/silk/fixed
|
|
||||||
opus/silk/float
|
|
||||||
opus/src
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(Opus::opus ALIAS opus)
|
|
1
externals/opus/opus
vendored
1
externals/opus/opus
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit ad8fe90db79b7d2a135e3dfd2ed6631b0c5662ab
|
|
2
externals/vcpkg
vendored
2
externals/vcpkg
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit cbf56573a987527b39272e88cbdd11389b78c6e4
|
Subproject commit ef2eef17340f3fbd679327d286fad06dd6e838ed
|
|
@ -47,6 +47,10 @@ android {
|
||||||
jniLibs.useLegacyPackaging = true
|
jniLibs.useLegacyPackaging = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
androidResources {
|
||||||
|
generateLocaleConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO If this is ever modified, change application_id in strings.xml
|
// TODO If this is ever modified, change application_id in strings.xml
|
||||||
applicationId = "org.yuzu.yuzu_emu"
|
applicationId = "org.yuzu.yuzu_emu"
|
||||||
|
|
|
@ -26,7 +26,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:isGame="true"
|
android:isGame="true"
|
||||||
android:appCategory="game"
|
android:appCategory="game"
|
||||||
android:localeConfig="@xml/locales_config"
|
|
||||||
android:banner="@drawable/tv_banner"
|
android:banner="@drawable/tv_banner"
|
||||||
android:fullBackupContent="@xml/data_extraction_rules"
|
android:fullBackupContent="@xml/data_extraction_rules"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules_api_31"
|
android:dataExtractionRules="@xml/data_extraction_rules_api_31"
|
||||||
|
|
|
@ -5,6 +5,7 @@ package org.yuzu.yuzu_emu
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
|
@ -16,7 +17,7 @@ import androidx.fragment.app.DialogFragment
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import org.yuzu.yuzu_emu.activities.EmulationActivity
|
import org.yuzu.yuzu_emu.activities.EmulationActivity
|
||||||
import org.yuzu.yuzu_emu.utils.DocumentsTree.Companion.isNativePath
|
import org.yuzu.yuzu_emu.utils.DocumentsTree
|
||||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
import org.yuzu.yuzu_emu.utils.FileUtil
|
||||||
import org.yuzu.yuzu_emu.utils.Log
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
import org.yuzu.yuzu_emu.utils.SerializableHelper.serializable
|
import org.yuzu.yuzu_emu.utils.SerializableHelper.serializable
|
||||||
|
@ -68,7 +69,7 @@ object NativeLibrary {
|
||||||
@Keep
|
@Keep
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun openContentUri(path: String?, openmode: String?): Int {
|
fun openContentUri(path: String?, openmode: String?): Int {
|
||||||
return if (isNativePath(path!!)) {
|
return if (DocumentsTree.isNativePath(path!!)) {
|
||||||
YuzuApplication.documentsTree!!.openContentUri(path, openmode)
|
YuzuApplication.documentsTree!!.openContentUri(path, openmode)
|
||||||
} else {
|
} else {
|
||||||
FileUtil.openContentUri(path, openmode)
|
FileUtil.openContentUri(path, openmode)
|
||||||
|
@ -78,7 +79,7 @@ object NativeLibrary {
|
||||||
@Keep
|
@Keep
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getSize(path: String?): Long {
|
fun getSize(path: String?): Long {
|
||||||
return if (isNativePath(path!!)) {
|
return if (DocumentsTree.isNativePath(path!!)) {
|
||||||
YuzuApplication.documentsTree!!.getFileSize(path)
|
YuzuApplication.documentsTree!!.getFileSize(path)
|
||||||
} else {
|
} else {
|
||||||
FileUtil.getFileSize(path)
|
FileUtil.getFileSize(path)
|
||||||
|
@ -88,23 +89,41 @@ object NativeLibrary {
|
||||||
@Keep
|
@Keep
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun exists(path: String?): Boolean {
|
fun exists(path: String?): Boolean {
|
||||||
return if (isNativePath(path!!)) {
|
return if (DocumentsTree.isNativePath(path!!)) {
|
||||||
YuzuApplication.documentsTree!!.exists(path)
|
YuzuApplication.documentsTree!!.exists(path)
|
||||||
} else {
|
} else {
|
||||||
FileUtil.exists(path)
|
FileUtil.exists(path, suppressLog = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isDirectory(path: String?): Boolean {
|
fun isDirectory(path: String?): Boolean {
|
||||||
return if (isNativePath(path!!)) {
|
return if (DocumentsTree.isNativePath(path!!)) {
|
||||||
YuzuApplication.documentsTree!!.isDirectory(path)
|
YuzuApplication.documentsTree!!.isDirectory(path)
|
||||||
} else {
|
} else {
|
||||||
FileUtil.isDirectory(path)
|
FileUtil.isDirectory(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
@JvmStatic
|
||||||
|
fun getParentDirectory(path: String): String =
|
||||||
|
if (DocumentsTree.isNativePath(path)) {
|
||||||
|
YuzuApplication.documentsTree!!.getParentDirectory(path)
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
@JvmStatic
|
||||||
|
fun getFilename(path: String): String =
|
||||||
|
if (DocumentsTree.isNativePath(path)) {
|
||||||
|
YuzuApplication.documentsTree!!.getFilename(path)
|
||||||
|
} else {
|
||||||
|
FileUtil.getFilename(Uri.parse(path))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if pro controller isn't available and handheld is
|
* Returns true if pro controller isn't available and handheld is
|
||||||
*/
|
*/
|
||||||
|
@ -215,32 +234,6 @@ object NativeLibrary {
|
||||||
|
|
||||||
external fun initGameIni(gameID: String?)
|
external fun initGameIni(gameID: String?)
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the embedded icon within the given ROM.
|
|
||||||
*
|
|
||||||
* @param filename the file path to the ROM.
|
|
||||||
* @return a byte array containing the JPEG data for the icon.
|
|
||||||
*/
|
|
||||||
external fun getIcon(filename: String): ByteArray
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the embedded title of the given ISO/ROM.
|
|
||||||
*
|
|
||||||
* @param filename The file path to the ISO/ROM.
|
|
||||||
* @return the embedded title of the ISO/ROM.
|
|
||||||
*/
|
|
||||||
external fun getTitle(filename: String): String
|
|
||||||
|
|
||||||
external fun getDescription(filename: String): String
|
|
||||||
|
|
||||||
external fun getGameId(filename: String): String
|
|
||||||
|
|
||||||
external fun getRegions(filename: String): String
|
|
||||||
|
|
||||||
external fun getCompany(filename: String): String
|
|
||||||
|
|
||||||
external fun isHomebrew(filename: String): Boolean
|
|
||||||
|
|
||||||
external fun setAppDirectory(directory: String)
|
external fun setAppDirectory(directory: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -259,7 +252,7 @@ object NativeLibrary {
|
||||||
|
|
||||||
external fun reloadKeys(): Boolean
|
external fun reloadKeys(): Boolean
|
||||||
|
|
||||||
external fun initializeEmulation()
|
external fun initializeSystem(reload: Boolean)
|
||||||
|
|
||||||
external fun defaultCPUCore(): Int
|
external fun defaultCPUCore(): Int
|
||||||
|
|
||||||
|
@ -293,11 +286,6 @@ object NativeLibrary {
|
||||||
*/
|
*/
|
||||||
external fun stopEmulation()
|
external fun stopEmulation()
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the in-memory ROM metadata cache.
|
|
||||||
*/
|
|
||||||
external fun resetRomMetadata()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if emulation is running (or is paused).
|
* Returns true if emulation is running (or is paused).
|
||||||
*/
|
*/
|
||||||
|
@ -474,12 +462,12 @@ object NativeLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setEmulationActivity(emulationActivity: EmulationActivity?) {
|
fun setEmulationActivity(emulationActivity: EmulationActivity?) {
|
||||||
Log.verbose("[NativeLibrary] Registering EmulationActivity.")
|
Log.debug("[NativeLibrary] Registering EmulationActivity.")
|
||||||
sEmulationActivity = WeakReference(emulationActivity)
|
sEmulationActivity = WeakReference(emulationActivity)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearEmulationActivity() {
|
fun clearEmulationActivity() {
|
||||||
Log.verbose("[NativeLibrary] Unregistering EmulationActivity.")
|
Log.debug("[NativeLibrary] Unregistering EmulationActivity.")
|
||||||
sEmulationActivity.clear()
|
sEmulationActivity.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,6 +505,36 @@ object NativeLibrary {
|
||||||
*/
|
*/
|
||||||
external fun initializeEmptyUserDirectory()
|
external fun initializeEmptyUserDirectory()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the launch path for a given applet. It is the caller's responsibility to also
|
||||||
|
* set the system's current applet ID before trying to launch the nca given by this function.
|
||||||
|
*
|
||||||
|
* @param id The applet entry ID
|
||||||
|
* @return The applet's launch path
|
||||||
|
*/
|
||||||
|
external fun getAppletLaunchPath(id: Long): String
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the system's current applet ID before launching.
|
||||||
|
*
|
||||||
|
* @param appletId One of the ids in the Service::AM::Applets::AppletId enum
|
||||||
|
*/
|
||||||
|
external fun setCurrentAppletId(appletId: Int)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cabinet mode for launching the cabinet applet.
|
||||||
|
*
|
||||||
|
* @param cabinetMode One of the modes that corresponds to the enum in Service::NFP::CabinetMode
|
||||||
|
*/
|
||||||
|
external fun setCabinetMode(cabinetMode: Int)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether NAND contents are available and valid.
|
||||||
|
*
|
||||||
|
* @return 'true' if firmware is available
|
||||||
|
*/
|
||||||
|
external fun isFirmwareAvailable(): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Button type for use in onTouchEvent
|
* Button type for use in onTouchEvent
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.io.File
|
||||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||||
import org.yuzu.yuzu_emu.utils.DocumentsTree
|
import org.yuzu.yuzu_emu.utils.DocumentsTree
|
||||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||||
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
|
|
||||||
fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir
|
fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ class YuzuApplication : Application() {
|
||||||
DirectoryInitialization.start()
|
DirectoryInitialization.start()
|
||||||
GpuDriverHelper.initializeDriverParameters()
|
GpuDriverHelper.initializeDriverParameters()
|
||||||
NativeLibrary.logDeviceInfo()
|
NativeLibrary.logDeviceInfo()
|
||||||
|
Log.logDeviceInfo()
|
||||||
|
|
||||||
createNotificationChannels()
|
createNotificationChannels()
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,9 @@ import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||||
import org.yuzu.yuzu_emu.model.EmulationViewModel
|
import org.yuzu.yuzu_emu.model.EmulationViewModel
|
||||||
import org.yuzu.yuzu_emu.model.Game
|
import org.yuzu.yuzu_emu.model.Game
|
||||||
import org.yuzu.yuzu_emu.utils.ControllerMappingHelper
|
|
||||||
import org.yuzu.yuzu_emu.utils.ForegroundService
|
import org.yuzu.yuzu_emu.utils.ForegroundService
|
||||||
import org.yuzu.yuzu_emu.utils.InputHandler
|
import org.yuzu.yuzu_emu.utils.InputHandler
|
||||||
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
import org.yuzu.yuzu_emu.utils.MemoryUtil
|
import org.yuzu.yuzu_emu.utils.MemoryUtil
|
||||||
import org.yuzu.yuzu_emu.utils.NfcReader
|
import org.yuzu.yuzu_emu.utils.NfcReader
|
||||||
import org.yuzu.yuzu_emu.utils.ThemeHelper
|
import org.yuzu.yuzu_emu.utils.ThemeHelper
|
||||||
|
@ -57,17 +57,16 @@ import kotlin.math.roundToInt
|
||||||
class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
||||||
private lateinit var binding: ActivityEmulationBinding
|
private lateinit var binding: ActivityEmulationBinding
|
||||||
|
|
||||||
private var controllerMappingHelper: ControllerMappingHelper? = null
|
|
||||||
|
|
||||||
var isActivityRecreated = false
|
var isActivityRecreated = false
|
||||||
private lateinit var nfcReader: NfcReader
|
private lateinit var nfcReader: NfcReader
|
||||||
private lateinit var inputHandler: InputHandler
|
|
||||||
|
|
||||||
private val gyro = FloatArray(3)
|
private val gyro = FloatArray(3)
|
||||||
private val accel = FloatArray(3)
|
private val accel = FloatArray(3)
|
||||||
private var motionTimestamp: Long = 0
|
private var motionTimestamp: Long = 0
|
||||||
private var flipMotionOrientation: Boolean = false
|
private var flipMotionOrientation: Boolean = false
|
||||||
|
|
||||||
|
private var controllerIds = InputHandler.getGameControllerIds()
|
||||||
|
|
||||||
private val actionPause = "ACTION_EMULATOR_PAUSE"
|
private val actionPause = "ACTION_EMULATOR_PAUSE"
|
||||||
private val actionPlay = "ACTION_EMULATOR_PLAY"
|
private val actionPlay = "ACTION_EMULATOR_PLAY"
|
||||||
private val actionMute = "ACTION_EMULATOR_MUTE"
|
private val actionMute = "ACTION_EMULATOR_MUTE"
|
||||||
|
@ -82,6 +81,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
Log.gameLaunched = true
|
||||||
ThemeHelper.setTheme(this)
|
ThemeHelper.setTheme(this)
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -95,8 +95,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
||||||
|
|
||||||
isActivityRecreated = savedInstanceState != null
|
isActivityRecreated = savedInstanceState != null
|
||||||
|
|
||||||
controllerMappingHelper = ControllerMappingHelper()
|
|
||||||
|
|
||||||
// Set these options now so that the SurfaceView the game renders into is the right size.
|
// Set these options now so that the SurfaceView the game renders into is the right size.
|
||||||
enableFullscreenImmersive()
|
enableFullscreenImmersive()
|
||||||
|
|
||||||
|
@ -105,12 +103,11 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
||||||
nfcReader = NfcReader(this)
|
nfcReader = NfcReader(this)
|
||||||
nfcReader.initialize()
|
nfcReader.initialize()
|
||||||
|
|
||||||
inputHandler = InputHandler()
|
InputHandler.initialize()
|
||||||
inputHandler.initialize()
|
|
||||||
|
|
||||||
val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||||
if (!preferences.getBoolean(Settings.PREF_MEMORY_WARNING_SHOWN, false)) {
|
if (!preferences.getBoolean(Settings.PREF_MEMORY_WARNING_SHOWN, false)) {
|
||||||
if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.Gb)) {
|
if (MemoryUtil.isLessThan(MemoryUtil.REQUIRED_MEMORY, MemoryUtil.totalMemory)) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this,
|
this,
|
||||||
getString(
|
getString(
|
||||||
|
@ -162,6 +159,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
nfcReader.startScanning()
|
nfcReader.startScanning()
|
||||||
startMotionSensorListener()
|
startMotionSensorListener()
|
||||||
|
InputHandler.updateControllerIds()
|
||||||
|
|
||||||
buildPictureInPictureParams()
|
buildPictureInPictureParams()
|
||||||
}
|
}
|
||||||
|
@ -195,7 +193,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
||||||
return super.dispatchKeyEvent(event)
|
return super.dispatchKeyEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
return inputHandler.dispatchKeyEvent(event)
|
return InputHandler.dispatchKeyEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispatchGenericMotionEvent(event: MotionEvent): Boolean {
|
override fun dispatchGenericMotionEvent(event: MotionEvent): Boolean {
|
||||||
|
@ -210,7 +208,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return inputHandler.dispatchGenericMotionEvent(event)
|
return InputHandler.dispatchGenericMotionEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSensorChanged(event: SensorEvent) {
|
override fun onSensorChanged(event: SensorEvent) {
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.adapters
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.res.ResourcesCompat
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.navigation.findNavController
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
||||||
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
|
import org.yuzu.yuzu_emu.databinding.CardAppletOptionBinding
|
||||||
|
import org.yuzu.yuzu_emu.model.Applet
|
||||||
|
import org.yuzu.yuzu_emu.model.AppletInfo
|
||||||
|
import org.yuzu.yuzu_emu.model.Game
|
||||||
|
|
||||||
|
class AppletAdapter(val activity: FragmentActivity, var applets: List<Applet>) :
|
||||||
|
RecyclerView.Adapter<AppletAdapter.AppletViewHolder>(),
|
||||||
|
View.OnClickListener {
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(
|
||||||
|
parent: ViewGroup,
|
||||||
|
viewType: Int
|
||||||
|
): AppletAdapter.AppletViewHolder {
|
||||||
|
CardAppletOptionBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
.apply { root.setOnClickListener(this@AppletAdapter) }
|
||||||
|
.also { return AppletViewHolder(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: AppletViewHolder, position: Int) =
|
||||||
|
holder.bind(applets[position])
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = applets.size
|
||||||
|
|
||||||
|
override fun onClick(view: View) {
|
||||||
|
val applet = (view.tag as AppletViewHolder).applet
|
||||||
|
val appletPath = NativeLibrary.getAppletLaunchPath(applet.appletInfo.entryId)
|
||||||
|
if (appletPath.isEmpty()) {
|
||||||
|
Toast.makeText(
|
||||||
|
YuzuApplication.appContext,
|
||||||
|
R.string.applets_error_applet,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (applet.appletInfo == AppletInfo.Cabinet) {
|
||||||
|
view.findNavController()
|
||||||
|
.navigate(R.id.action_appletLauncherFragment_to_cabinetLauncherDialogFragment)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeLibrary.setCurrentAppletId(applet.appletInfo.appletId)
|
||||||
|
val appletGame = Game(
|
||||||
|
title = YuzuApplication.appContext.getString(applet.titleId),
|
||||||
|
path = appletPath
|
||||||
|
)
|
||||||
|
val action = HomeNavigationDirections.actionGlobalEmulationActivity(appletGame)
|
||||||
|
view.findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class AppletViewHolder(val binding: CardAppletOptionBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
lateinit var applet: Applet
|
||||||
|
|
||||||
|
init {
|
||||||
|
itemView.tag = this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bind(applet: Applet) {
|
||||||
|
this.applet = applet
|
||||||
|
|
||||||
|
binding.title.setText(applet.titleId)
|
||||||
|
binding.description.setText(applet.descriptionId)
|
||||||
|
binding.icon.setImageDrawable(
|
||||||
|
ResourcesCompat.getDrawable(
|
||||||
|
binding.icon.context.resources,
|
||||||
|
applet.iconId,
|
||||||
|
binding.icon.context.theme
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.adapters
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.content.res.ResourcesCompat
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
||||||
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
|
import org.yuzu.yuzu_emu.databinding.DialogListItemBinding
|
||||||
|
import org.yuzu.yuzu_emu.model.CabinetMode
|
||||||
|
import org.yuzu.yuzu_emu.adapters.CabinetLauncherDialogAdapter.CabinetModeViewHolder
|
||||||
|
import org.yuzu.yuzu_emu.model.AppletInfo
|
||||||
|
import org.yuzu.yuzu_emu.model.Game
|
||||||
|
|
||||||
|
class CabinetLauncherDialogAdapter(val fragment: Fragment) :
|
||||||
|
RecyclerView.Adapter<CabinetModeViewHolder>(),
|
||||||
|
View.OnClickListener {
|
||||||
|
private val cabinetModes = CabinetMode.values().copyOfRange(1, CabinetMode.values().size)
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CabinetModeViewHolder {
|
||||||
|
DialogListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
.apply { root.setOnClickListener(this@CabinetLauncherDialogAdapter) }
|
||||||
|
.also { return CabinetModeViewHolder(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = cabinetModes.size
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: CabinetModeViewHolder, position: Int) =
|
||||||
|
holder.bind(cabinetModes[position])
|
||||||
|
|
||||||
|
override fun onClick(view: View) {
|
||||||
|
val mode = (view.tag as CabinetModeViewHolder).cabinetMode
|
||||||
|
val appletPath = NativeLibrary.getAppletLaunchPath(AppletInfo.Cabinet.entryId)
|
||||||
|
NativeLibrary.setCurrentAppletId(AppletInfo.Cabinet.appletId)
|
||||||
|
NativeLibrary.setCabinetMode(mode.id)
|
||||||
|
val appletGame = Game(
|
||||||
|
title = YuzuApplication.appContext.getString(R.string.cabinet_applet),
|
||||||
|
path = appletPath
|
||||||
|
)
|
||||||
|
val action = HomeNavigationDirections.actionGlobalEmulationActivity(appletGame)
|
||||||
|
fragment.findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class CabinetModeViewHolder(val binding: DialogListItemBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
lateinit var cabinetMode: CabinetMode
|
||||||
|
|
||||||
|
init {
|
||||||
|
itemView.tag = this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bind(cabinetMode: CabinetMode) {
|
||||||
|
this.cabinetMode = cabinetMode
|
||||||
|
binding.icon.setImageDrawable(
|
||||||
|
ResourcesCompat.getDrawable(
|
||||||
|
binding.icon.context.resources,
|
||||||
|
cabinetMode.iconId,
|
||||||
|
binding.icon.context.theme
|
||||||
|
)
|
||||||
|
)
|
||||||
|
binding.title.setText(cabinetMode.titleId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -147,7 +147,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
|
|
||||||
private class DiffCallback : DiffUtil.ItemCallback<Game>() {
|
private class DiffCallback : DiffUtil.ItemCallback<Game>() {
|
||||||
override fun areItemsTheSame(oldItem: Game, newItem: Game): Boolean {
|
override fun areItemsTheSame(oldItem: Game, newItem: Game): Boolean {
|
||||||
return oldItem.gameId == newItem.gameId
|
return oldItem.programId == newItem.programId
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean {
|
override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean {
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.navigation.findNavController
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
import org.yuzu.yuzu_emu.adapters.AppletAdapter
|
||||||
|
import org.yuzu.yuzu_emu.databinding.FragmentAppletLauncherBinding
|
||||||
|
import org.yuzu.yuzu_emu.model.Applet
|
||||||
|
import org.yuzu.yuzu_emu.model.AppletInfo
|
||||||
|
import org.yuzu.yuzu_emu.model.HomeViewModel
|
||||||
|
|
||||||
|
class AppletLauncherFragment : Fragment() {
|
||||||
|
private var _binding: FragmentAppletLauncherBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
private val homeViewModel: HomeViewModel by activityViewModels()
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||||
|
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||||
|
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentAppletLauncherBinding.inflate(inflater)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
homeViewModel.setNavigationVisibility(visible = false, animated = true)
|
||||||
|
homeViewModel.setStatusBarShadeVisibility(visible = false)
|
||||||
|
|
||||||
|
binding.toolbarApplets.setNavigationOnClickListener {
|
||||||
|
binding.root.findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
|
||||||
|
val applets = listOf(
|
||||||
|
Applet(
|
||||||
|
R.string.album_applet,
|
||||||
|
R.string.album_applet_description,
|
||||||
|
R.drawable.ic_album,
|
||||||
|
AppletInfo.PhotoViewer
|
||||||
|
),
|
||||||
|
Applet(
|
||||||
|
R.string.cabinet_applet,
|
||||||
|
R.string.cabinet_applet_description,
|
||||||
|
R.drawable.ic_nfc,
|
||||||
|
AppletInfo.Cabinet
|
||||||
|
),
|
||||||
|
Applet(
|
||||||
|
R.string.mii_edit_applet,
|
||||||
|
R.string.mii_edit_applet_description,
|
||||||
|
R.drawable.ic_mii,
|
||||||
|
AppletInfo.MiiEdit
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.listApplets.apply {
|
||||||
|
layoutManager = GridLayoutManager(
|
||||||
|
requireContext(),
|
||||||
|
resources.getInteger(R.integer.grid_columns)
|
||||||
|
)
|
||||||
|
adapter = AppletAdapter(requireActivity(), applets)
|
||||||
|
}
|
||||||
|
|
||||||
|
setInsets()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setInsets() =
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(
|
||||||
|
binding.root
|
||||||
|
) { _: View, windowInsets: WindowInsetsCompat ->
|
||||||
|
val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
|
||||||
|
|
||||||
|
val leftInsets = barInsets.left + cutoutInsets.left
|
||||||
|
val rightInsets = barInsets.right + cutoutInsets.right
|
||||||
|
|
||||||
|
val mlpAppBar = binding.toolbarApplets.layoutParams as ViewGroup.MarginLayoutParams
|
||||||
|
mlpAppBar.leftMargin = leftInsets
|
||||||
|
mlpAppBar.rightMargin = rightInsets
|
||||||
|
binding.toolbarApplets.layoutParams = mlpAppBar
|
||||||
|
|
||||||
|
val mlpListApplets =
|
||||||
|
binding.listApplets.layoutParams as ViewGroup.MarginLayoutParams
|
||||||
|
mlpListApplets.leftMargin = leftInsets
|
||||||
|
mlpListApplets.rightMargin = rightInsets
|
||||||
|
binding.listApplets.layoutParams = mlpListApplets
|
||||||
|
|
||||||
|
binding.listApplets.updatePadding(bottom = barInsets.bottom)
|
||||||
|
|
||||||
|
windowInsets
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
import org.yuzu.yuzu_emu.adapters.CabinetLauncherDialogAdapter
|
||||||
|
import org.yuzu.yuzu_emu.databinding.DialogListBinding
|
||||||
|
|
||||||
|
class CabinetLauncherDialogFragment : DialogFragment() {
|
||||||
|
private lateinit var binding: DialogListBinding
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
binding = DialogListBinding.inflate(layoutInflater)
|
||||||
|
binding.dialogList.apply {
|
||||||
|
layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
adapter = CabinetLauncherDialogAdapter(this@CabinetLauncherDialogFragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
return MaterialAlertDialogBuilder(requireContext())
|
||||||
|
.setTitle(R.string.cabinet_launcher)
|
||||||
|
.setView(binding.root)
|
||||||
|
.create()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.os.SystemClock
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
@ -25,6 +26,7 @@ import androidx.core.graphics.Insets
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
|
import androidx.drawerlayout.widget.DrawerLayout.DrawerListener
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
|
@ -156,6 +158,32 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
binding.showFpsText.setTextColor(Color.YELLOW)
|
binding.showFpsText.setTextColor(Color.YELLOW)
|
||||||
binding.doneControlConfig.setOnClickListener { stopConfiguringControls() }
|
binding.doneControlConfig.setOnClickListener { stopConfiguringControls() }
|
||||||
|
|
||||||
|
binding.drawerLayout.addDrawerListener(object : DrawerListener {
|
||||||
|
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
|
||||||
|
binding.surfaceInputOverlay.dispatchTouchEvent(
|
||||||
|
MotionEvent.obtain(
|
||||||
|
SystemClock.uptimeMillis(),
|
||||||
|
SystemClock.uptimeMillis() + 100,
|
||||||
|
MotionEvent.ACTION_UP,
|
||||||
|
0f,
|
||||||
|
0f,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDrawerOpened(drawerView: View) {
|
||||||
|
// No op
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDrawerClosed(drawerView: View) {
|
||||||
|
// No op
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDrawerStateChanged(newState: Int) {
|
||||||
|
// No op
|
||||||
|
}
|
||||||
|
})
|
||||||
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||||
binding.inGameMenu.getHeaderView(0).findViewById<TextView>(R.id.text_game_title).text =
|
binding.inGameMenu.getHeaderView(0).findViewById<TextView>(R.id.text_game_title).text =
|
||||||
game.title
|
game.title
|
||||||
|
@ -284,6 +312,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
ViewUtils.showView(binding.surfaceInputOverlay)
|
ViewUtils.showView(binding.surfaceInputOverlay)
|
||||||
ViewUtils.hideView(binding.loadingIndicator)
|
ViewUtils.hideView(binding.loadingIndicator)
|
||||||
|
|
||||||
|
emulationState.updateSurface()
|
||||||
|
|
||||||
// Setup overlay
|
// Setup overlay
|
||||||
updateShowFpsOverlay()
|
updateShowFpsOverlay()
|
||||||
}
|
}
|
||||||
|
@ -776,6 +806,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
fun updateSurface() {
|
||||||
|
if (surface != null) {
|
||||||
|
NativeLibrary.surfaceChanged(surface)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun clearSurface() {
|
fun clearSurface() {
|
||||||
if (surface == null) {
|
if (surface == null) {
|
||||||
|
|
|
@ -26,10 +26,11 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import com.google.android.material.transition.MaterialSharedAxis
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
import org.yuzu.yuzu_emu.BuildConfig
|
import org.yuzu.yuzu_emu.BuildConfig
|
||||||
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
||||||
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.adapters.HomeSettingAdapter
|
import org.yuzu.yuzu_emu.adapters.HomeSettingAdapter
|
||||||
import org.yuzu.yuzu_emu.databinding.FragmentHomeSettingsBinding
|
import org.yuzu.yuzu_emu.databinding.FragmentHomeSettingsBinding
|
||||||
|
@ -41,6 +42,7 @@ import org.yuzu.yuzu_emu.model.HomeViewModel
|
||||||
import org.yuzu.yuzu_emu.ui.main.MainActivity
|
import org.yuzu.yuzu_emu.ui.main.MainActivity
|
||||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
import org.yuzu.yuzu_emu.utils.FileUtil
|
||||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||||
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
|
|
||||||
class HomeSettingsFragment : Fragment() {
|
class HomeSettingsFragment : Fragment() {
|
||||||
private var _binding: FragmentHomeSettingsBinding? = null
|
private var _binding: FragmentHomeSettingsBinding? = null
|
||||||
|
@ -83,28 +85,6 @@ class HomeSettingsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
|
||||||
HomeSetting(
|
|
||||||
R.string.open_user_folder,
|
|
||||||
R.string.open_user_folder_description,
|
|
||||||
R.drawable.ic_folder_open,
|
|
||||||
{ openFileManager() }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
add(
|
|
||||||
HomeSetting(
|
|
||||||
R.string.preferences_theme,
|
|
||||||
R.string.theme_and_color_description,
|
|
||||||
R.drawable.ic_palette,
|
|
||||||
{
|
|
||||||
val action = HomeNavigationDirections.actionGlobalSettingsActivity(
|
|
||||||
null,
|
|
||||||
Settings.MenuTag.SECTION_THEME
|
|
||||||
)
|
|
||||||
binding.root.findNavController().navigate(action)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
add(
|
add(
|
||||||
HomeSetting(
|
HomeSetting(
|
||||||
R.string.gpu_driver_manager,
|
R.string.gpu_driver_manager,
|
||||||
|
@ -120,6 +100,20 @@ class HomeSettingsFragment : Fragment() {
|
||||||
driverViewModel.selectedDriverMetadata
|
driverViewModel.selectedDriverMetadata
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
add(
|
||||||
|
HomeSetting(
|
||||||
|
R.string.applets,
|
||||||
|
R.string.applets_description,
|
||||||
|
R.drawable.ic_applet,
|
||||||
|
{
|
||||||
|
binding.root.findNavController()
|
||||||
|
.navigate(R.id.action_homeSettingsFragment_to_appletLauncherFragment)
|
||||||
|
},
|
||||||
|
{ NativeLibrary.isFirmwareAvailable() },
|
||||||
|
R.string.applets_error_firmware,
|
||||||
|
R.string.applets_error_description
|
||||||
|
)
|
||||||
|
)
|
||||||
add(
|
add(
|
||||||
HomeSetting(
|
HomeSetting(
|
||||||
R.string.manage_yuzu_data,
|
R.string.manage_yuzu_data,
|
||||||
|
@ -155,6 +149,28 @@ class HomeSettingsFragment : Fragment() {
|
||||||
{ shareLog() }
|
{ shareLog() }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
add(
|
||||||
|
HomeSetting(
|
||||||
|
R.string.open_user_folder,
|
||||||
|
R.string.open_user_folder_description,
|
||||||
|
R.drawable.ic_folder_open,
|
||||||
|
{ openFileManager() }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
add(
|
||||||
|
HomeSetting(
|
||||||
|
R.string.preferences_theme,
|
||||||
|
R.string.theme_and_color_description,
|
||||||
|
R.drawable.ic_palette,
|
||||||
|
{
|
||||||
|
val action = HomeNavigationDirections.actionGlobalSettingsActivity(
|
||||||
|
null,
|
||||||
|
Settings.MenuTag.SECTION_THEME
|
||||||
|
)
|
||||||
|
binding.root.findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
add(
|
add(
|
||||||
HomeSetting(
|
HomeSetting(
|
||||||
R.string.about,
|
R.string.about,
|
||||||
|
@ -186,7 +202,8 @@ class HomeSettingsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.homeSettingsList.apply {
|
binding.homeSettingsList.apply {
|
||||||
layoutManager = LinearLayoutManager(requireContext())
|
layoutManager =
|
||||||
|
GridLayoutManager(requireContext(), resources.getInteger(R.integer.grid_columns))
|
||||||
adapter = HomeSettingAdapter(
|
adapter = HomeSettingAdapter(
|
||||||
requireActivity() as AppCompatActivity,
|
requireActivity() as AppCompatActivity,
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner,
|
||||||
|
@ -296,19 +313,32 @@ class HomeSettingsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Share the current log if we just returned from a game but share the old log
|
||||||
|
// if we just started the app and the old log exists.
|
||||||
private fun shareLog() {
|
private fun shareLog() {
|
||||||
val file = DocumentFile.fromSingleUri(
|
val currentLog = DocumentFile.fromSingleUri(
|
||||||
mainActivity,
|
mainActivity,
|
||||||
DocumentsContract.buildDocumentUri(
|
DocumentsContract.buildDocumentUri(
|
||||||
DocumentProvider.AUTHORITY,
|
DocumentProvider.AUTHORITY,
|
||||||
"${DocumentProvider.ROOT_ID}/log/yuzu_log.txt"
|
"${DocumentProvider.ROOT_ID}/log/yuzu_log.txt"
|
||||||
)
|
)
|
||||||
)!!
|
)!!
|
||||||
if (file.exists()) {
|
val oldLog = DocumentFile.fromSingleUri(
|
||||||
|
mainActivity,
|
||||||
|
DocumentsContract.buildDocumentUri(
|
||||||
|
DocumentProvider.AUTHORITY,
|
||||||
|
"${DocumentProvider.ROOT_ID}/log/yuzu_log.txt.old.txt"
|
||||||
|
)
|
||||||
|
)!!
|
||||||
|
|
||||||
val intent = Intent(Intent.ACTION_SEND)
|
val intent = Intent(Intent.ACTION_SEND)
|
||||||
.setDataAndType(file.uri, FileUtil.TEXT_PLAIN)
|
.setDataAndType(currentLog.uri, FileUtil.TEXT_PLAIN)
|
||||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
.putExtra(Intent.EXTRA_STREAM, file.uri)
|
if (!Log.gameLaunched && oldLog.exists()) {
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM, oldLog.uri)
|
||||||
|
startActivity(Intent.createChooser(intent, getText(R.string.share_log)))
|
||||||
|
} else if (currentLog.exists()) {
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM, currentLog.uri)
|
||||||
startActivity(Intent.createChooser(intent, getText(R.string.share_log)))
|
startActivity(Intent.createChooser(intent, getText(R.string.share_log)))
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.Html
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
@ -32,7 +33,9 @@ class MessageDialogFragment : DialogFragment() {
|
||||||
if (titleId != 0) dialog.setTitle(titleId)
|
if (titleId != 0) dialog.setTitle(titleId)
|
||||||
if (titleString.isNotEmpty()) dialog.setTitle(titleString)
|
if (titleString.isNotEmpty()) dialog.setTitle(titleString)
|
||||||
|
|
||||||
if (descriptionId != 0) dialog.setMessage(descriptionId)
|
if (descriptionId != 0) {
|
||||||
|
dialog.setMessage(Html.fromHtml(getString(descriptionId), Html.FROM_HTML_MODE_LEGACY))
|
||||||
|
}
|
||||||
if (descriptionString.isNotEmpty()) dialog.setMessage(descriptionString)
|
if (descriptionString.isNotEmpty()) dialog.setMessage(descriptionString)
|
||||||
|
|
||||||
if (helpLinkId != 0) {
|
if (helpLinkId != 0) {
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.model
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
|
||||||
|
data class Applet(
|
||||||
|
@StringRes val titleId: Int,
|
||||||
|
@StringRes val descriptionId: Int,
|
||||||
|
@DrawableRes val iconId: Int,
|
||||||
|
val appletInfo: AppletInfo,
|
||||||
|
val cabinetMode: CabinetMode = CabinetMode.None
|
||||||
|
)
|
||||||
|
|
||||||
|
// Combination of Common::AM::Applets::AppletId enum and the entry id
|
||||||
|
enum class AppletInfo(val appletId: Int, val entryId: Long = 0) {
|
||||||
|
None(0x00),
|
||||||
|
Application(0x01),
|
||||||
|
OverlayDisplay(0x02),
|
||||||
|
QLaunch(0x03),
|
||||||
|
Starter(0x04),
|
||||||
|
Auth(0x0A),
|
||||||
|
Cabinet(0x0B, 0x0100000000001002),
|
||||||
|
Controller(0x0C),
|
||||||
|
DataErase(0x0D),
|
||||||
|
Error(0x0E),
|
||||||
|
NetConnect(0x0F),
|
||||||
|
ProfileSelect(0x10),
|
||||||
|
SoftwareKeyboard(0x11),
|
||||||
|
MiiEdit(0x12, 0x0100000000001009),
|
||||||
|
Web(0x13),
|
||||||
|
Shop(0x14),
|
||||||
|
PhotoViewer(0x015, 0x010000000000100D),
|
||||||
|
Settings(0x16),
|
||||||
|
OfflineWeb(0x17),
|
||||||
|
LoginShare(0x18),
|
||||||
|
WebAuth(0x19),
|
||||||
|
MyPage(0x1A)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matches enum in Service::NFP::CabinetMode with extra metadata
|
||||||
|
enum class CabinetMode(
|
||||||
|
val id: Int,
|
||||||
|
@StringRes val titleId: Int = 0,
|
||||||
|
@DrawableRes val iconId: Int = 0
|
||||||
|
) {
|
||||||
|
None(-1),
|
||||||
|
StartNicknameAndOwnerSettings(0, R.string.cabinet_nickname_and_owner, R.drawable.ic_edit),
|
||||||
|
StartGameDataEraser(1, R.string.cabinet_game_data_eraser, R.drawable.ic_refresh),
|
||||||
|
StartRestorer(2, R.string.cabinet_restorer, R.drawable.ic_restore),
|
||||||
|
StartFormatter(3, R.string.cabinet_formatter, R.drawable.ic_clear)
|
||||||
|
}
|
|
@ -11,16 +11,15 @@ import kotlinx.serialization.Serializable
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@Serializable
|
@Serializable
|
||||||
class Game(
|
class Game(
|
||||||
val title: String,
|
val title: String = "",
|
||||||
val description: String,
|
|
||||||
val regions: String,
|
|
||||||
val path: String,
|
val path: String,
|
||||||
val gameId: String,
|
val programId: String = "",
|
||||||
val company: String,
|
val developer: String = "",
|
||||||
val isHomebrew: Boolean
|
val version: String = "",
|
||||||
|
val isHomebrew: Boolean = false
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
val keyAddedToLibraryTime get() = "${gameId}_AddedToLibraryTime"
|
val keyAddedToLibraryTime get() = "${programId}_AddedToLibraryTime"
|
||||||
val keyLastPlayedTime get() = "${gameId}_LastPlayed"
|
val keyLastPlayedTime get() = "${programId}_LastPlayed"
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is Game) {
|
if (other !is Game) {
|
||||||
|
@ -32,11 +31,9 @@ class Game(
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
var result = title.hashCode()
|
var result = title.hashCode()
|
||||||
result = 31 * result + description.hashCode()
|
|
||||||
result = 31 * result + regions.hashCode()
|
|
||||||
result = 31 * result + path.hashCode()
|
result = 31 * result + path.hashCode()
|
||||||
result = 31 * result + gameId.hashCode()
|
result = 31 * result + programId.hashCode()
|
||||||
result = 31 * result + company.hashCode()
|
result = 31 * result + developer.hashCode()
|
||||||
result = 31 * result + isHomebrew.hashCode()
|
result = 31 * result + isHomebrew.hashCode()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,15 +14,13 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
|
||||||
import kotlinx.serialization.MissingFieldException
|
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
import org.yuzu.yuzu_emu.utils.GameHelper
|
import org.yuzu.yuzu_emu.utils.GameHelper
|
||||||
|
import org.yuzu.yuzu_emu.utils.GameMetadata
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
|
||||||
class GamesViewModel : ViewModel() {
|
class GamesViewModel : ViewModel() {
|
||||||
val games: StateFlow<List<Game>> get() = _games
|
val games: StateFlow<List<Game>> get() = _games
|
||||||
private val _games = MutableStateFlow(emptyList<Game>())
|
private val _games = MutableStateFlow(emptyList<Game>())
|
||||||
|
@ -49,19 +47,25 @@ class GamesViewModel : ViewModel() {
|
||||||
// Retrieve list of cached games
|
// Retrieve list of cached games
|
||||||
val storedGames = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
val storedGames = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||||
.getStringSet(GameHelper.KEY_GAMES, emptySet())
|
.getStringSet(GameHelper.KEY_GAMES, emptySet())
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
if (storedGames!!.isNotEmpty()) {
|
if (storedGames!!.isNotEmpty()) {
|
||||||
val deserializedGames = mutableSetOf<Game>()
|
val deserializedGames = mutableSetOf<Game>()
|
||||||
storedGames.forEach {
|
storedGames.forEach {
|
||||||
val game: Game
|
val game: Game
|
||||||
try {
|
try {
|
||||||
game = Json.decodeFromString(it)
|
game = Json.decodeFromString(it)
|
||||||
} catch (e: MissingFieldException) {
|
} catch (e: Exception) {
|
||||||
|
// We don't care about any errors related to parsing the game cache
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
|
|
||||||
val gameExists =
|
val gameExists =
|
||||||
DocumentFile.fromSingleUri(YuzuApplication.appContext, Uri.parse(game.path))
|
DocumentFile.fromSingleUri(
|
||||||
?.exists()
|
YuzuApplication.appContext,
|
||||||
|
Uri.parse(game.path)
|
||||||
|
)?.exists()
|
||||||
if (gameExists == true) {
|
if (gameExists == true) {
|
||||||
deserializedGames.add(game)
|
deserializedGames.add(game)
|
||||||
}
|
}
|
||||||
|
@ -70,6 +74,8 @@ class GamesViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
reloadGames(false)
|
reloadGames(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun setGames(games: List<Game>) {
|
fun setGames(games: List<Game>) {
|
||||||
val sortedList = games.sortedWith(
|
val sortedList = games.sortedWith(
|
||||||
|
@ -106,7 +112,7 @@ class GamesViewModel : ViewModel() {
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
NativeLibrary.resetRomMetadata()
|
GameMetadata.resetMetadata()
|
||||||
setGames(GameHelper.getGames())
|
setGames(GameHelper.getGames())
|
||||||
_isReloading.value = false
|
_isReloading.value = false
|
||||||
|
|
||||||
|
|
|
@ -403,6 +403,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
} else {
|
} else {
|
||||||
firmwarePath.deleteRecursively()
|
firmwarePath.deleteRecursively()
|
||||||
cacheFirmwareDir.copyRecursively(firmwarePath, true)
|
cacheFirmwareDir.copyRecursively(firmwarePath, true)
|
||||||
|
NativeLibrary.initializeSystem(true)
|
||||||
getString(R.string.save_file_imported_success)
|
getString(R.string.save_file_imported_success)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -648,7 +649,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reinitialize relevant data
|
// Reinitialize relevant data
|
||||||
NativeLibrary.initializeEmulation()
|
NativeLibrary.initializeSystem(true)
|
||||||
gamesViewModel.reloadGames(false)
|
gamesViewModel.reloadGames(false)
|
||||||
|
|
||||||
return@newInstance getString(R.string.user_data_import_success)
|
return@newInstance getString(R.string.user_data_import_success)
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.utils
|
|
||||||
|
|
||||||
import android.view.InputDevice
|
|
||||||
import android.view.KeyEvent
|
|
||||||
import android.view.MotionEvent
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some controllers have incorrect mappings. This class has special-case fixes for them.
|
|
||||||
*/
|
|
||||||
class ControllerMappingHelper {
|
|
||||||
/**
|
|
||||||
* Some controllers report extra button presses that can be ignored.
|
|
||||||
*/
|
|
||||||
fun shouldKeyBeIgnored(inputDevice: InputDevice, keyCode: Int): Boolean {
|
|
||||||
return if (isDualShock4(inputDevice)) {
|
|
||||||
// The two analog triggers generate analog motion events as well as a keycode.
|
|
||||||
// We always prefer to use the analog values, so throw away the button press
|
|
||||||
keyCode == KeyEvent.KEYCODE_BUTTON_L2 || keyCode == KeyEvent.KEYCODE_BUTTON_R2
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scale an axis to be zero-centered with a proper range.
|
|
||||||
*/
|
|
||||||
fun scaleAxis(inputDevice: InputDevice, axis: Int, value: Float): Float {
|
|
||||||
if (isDualShock4(inputDevice)) {
|
|
||||||
// Android doesn't have correct mappings for this controller's triggers. It reports them
|
|
||||||
// as RX & RY, centered at -1.0, and with a range of [-1.0, 1.0]
|
|
||||||
// Scale them to properly zero-centered with a range of [0.0, 1.0].
|
|
||||||
if (axis == MotionEvent.AXIS_RX || axis == MotionEvent.AXIS_RY) {
|
|
||||||
return (value + 1) / 2.0f
|
|
||||||
}
|
|
||||||
} else if (isXboxOneWireless(inputDevice)) {
|
|
||||||
// Same as the DualShock 4, the mappings are missing.
|
|
||||||
if (axis == MotionEvent.AXIS_Z || axis == MotionEvent.AXIS_RZ) {
|
|
||||||
return (value + 1) / 2.0f
|
|
||||||
}
|
|
||||||
if (axis == MotionEvent.AXIS_GENERIC_1) {
|
|
||||||
// This axis is stuck at ~.5. Ignore it.
|
|
||||||
return 0.0f
|
|
||||||
}
|
|
||||||
} else if (isMogaPro2Hid(inputDevice)) {
|
|
||||||
// This controller has a broken axis that reports a constant value. Ignore it.
|
|
||||||
if (axis == MotionEvent.AXIS_GENERIC_1) {
|
|
||||||
return 0.0f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sony DualShock 4 controller
|
|
||||||
private fun isDualShock4(inputDevice: InputDevice): Boolean {
|
|
||||||
return inputDevice.vendorId == 0x54c && inputDevice.productId == 0x9cc
|
|
||||||
}
|
|
||||||
|
|
||||||
// Microsoft Xbox One controller
|
|
||||||
private fun isXboxOneWireless(inputDevice: InputDevice): Boolean {
|
|
||||||
return inputDevice.vendorId == 0x45e && inputDevice.productId == 0x2e0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Moga Pro 2 HID
|
|
||||||
private fun isMogaPro2Hid(inputDevice: InputDevice): Boolean {
|
|
||||||
return inputDevice.vendorId == 0x20d6 && inputDevice.productId == 0x6271
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,7 +15,7 @@ object DirectoryInitialization {
|
||||||
fun start() {
|
fun start() {
|
||||||
if (!areDirectoriesReady) {
|
if (!areDirectoriesReady) {
|
||||||
initializeInternalStorage()
|
initializeInternalStorage()
|
||||||
NativeLibrary.initializeEmulation()
|
NativeLibrary.initializeSystem(false)
|
||||||
areDirectoriesReady = true
|
areDirectoriesReady = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,23 @@ class DocumentsTree {
|
||||||
return node != null && node.isDirectory
|
return node != null && node.isDirectory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getParentDirectory(filepath: String): String {
|
||||||
|
val node = resolvePath(filepath)!!
|
||||||
|
val parentNode = node.parent
|
||||||
|
if (parentNode != null && parentNode.isDirectory) {
|
||||||
|
return parentNode.uri!!.toString()
|
||||||
|
}
|
||||||
|
return node.uri!!.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFilename(filepath: String): String {
|
||||||
|
val node = resolvePath(filepath)
|
||||||
|
if (node != null) {
|
||||||
|
return node.name!!
|
||||||
|
}
|
||||||
|
return filepath
|
||||||
|
}
|
||||||
|
|
||||||
private fun resolvePath(filepath: String): DocumentsNode? {
|
private fun resolvePath(filepath: String): DocumentsNode? {
|
||||||
val tokens = StringTokenizer(filepath, File.separator, false)
|
val tokens = StringTokenizer(filepath, File.separator, false)
|
||||||
var iterator = root
|
var iterator = root
|
||||||
|
|
|
@ -144,7 +144,7 @@ object FileUtil {
|
||||||
* @param path Native content uri path
|
* @param path Native content uri path
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
fun exists(path: String?): Boolean {
|
fun exists(path: String?, suppressLog: Boolean = false): Boolean {
|
||||||
var c: Cursor? = null
|
var c: Cursor? = null
|
||||||
try {
|
try {
|
||||||
val mUri = Uri.parse(path)
|
val mUri = Uri.parse(path)
|
||||||
|
@ -152,7 +152,9 @@ object FileUtil {
|
||||||
c = context.contentResolver.query(mUri, columns, null, null, null)
|
c = context.contentResolver.query(mUri, columns, null, null, null)
|
||||||
return c!!.count > 0
|
return c!!.count > 0
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
if (!suppressLog) {
|
||||||
Log.info("[FileUtil] Cannot find file from given path, error: " + e.message)
|
Log.info("[FileUtil] Cannot find file from given path, error: " + e.message)
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
closeQuietly(c)
|
closeQuietly(c)
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,27 +71,26 @@ object GameHelper {
|
||||||
|
|
||||||
fun getGame(uri: Uri, addedToLibrary: Boolean): Game {
|
fun getGame(uri: Uri, addedToLibrary: Boolean): Game {
|
||||||
val filePath = uri.toString()
|
val filePath = uri.toString()
|
||||||
var name = NativeLibrary.getTitle(filePath)
|
var name = GameMetadata.getTitle(filePath)
|
||||||
|
|
||||||
// If the game's title field is empty, use the filename.
|
// If the game's title field is empty, use the filename.
|
||||||
if (name.isEmpty()) {
|
if (name.isEmpty()) {
|
||||||
name = FileUtil.getFilename(uri)
|
name = FileUtil.getFilename(uri)
|
||||||
}
|
}
|
||||||
var gameId = NativeLibrary.getGameId(filePath)
|
var programId = GameMetadata.getProgramId(filePath)
|
||||||
|
|
||||||
// If the game's ID field is empty, use the filename without extension.
|
// If the game's ID field is empty, use the filename without extension.
|
||||||
if (gameId.isEmpty()) {
|
if (programId.isEmpty()) {
|
||||||
gameId = name.substring(0, name.lastIndexOf("."))
|
programId = name.substring(0, name.lastIndexOf("."))
|
||||||
}
|
}
|
||||||
|
|
||||||
val newGame = Game(
|
val newGame = Game(
|
||||||
name,
|
name,
|
||||||
NativeLibrary.getDescription(filePath).replace("\n", " "),
|
|
||||||
NativeLibrary.getRegions(filePath),
|
|
||||||
filePath,
|
filePath,
|
||||||
gameId,
|
programId,
|
||||||
NativeLibrary.getCompany(filePath),
|
GameMetadata.getDeveloper(filePath),
|
||||||
NativeLibrary.isHomebrew(filePath)
|
GameMetadata.getVersion(filePath),
|
||||||
|
GameMetadata.getIsHomebrew(filePath)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (addedToLibrary) {
|
if (addedToLibrary) {
|
||||||
|
|
|
@ -18,7 +18,6 @@ import coil.key.Keyer
|
||||||
import coil.memory.MemoryCache
|
import coil.memory.MemoryCache
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import coil.request.Options
|
import coil.request.Options
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
import org.yuzu.yuzu_emu.model.Game
|
import org.yuzu.yuzu_emu.model.Game
|
||||||
|
@ -36,7 +35,7 @@ class GameIconFetcher(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun decodeGameIcon(uri: String): Bitmap? {
|
private fun decodeGameIcon(uri: String): Bitmap? {
|
||||||
val data = NativeLibrary.getIcon(uri)
|
val data = GameMetadata.getIcon(uri)
|
||||||
return BitmapFactory.decodeByteArray(
|
return BitmapFactory.decodeByteArray(
|
||||||
data,
|
data,
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.utils
|
||||||
|
|
||||||
|
object GameMetadata {
|
||||||
|
external fun getTitle(path: String): String
|
||||||
|
|
||||||
|
external fun getProgramId(path: String): String
|
||||||
|
|
||||||
|
external fun getDeveloper(path: String): String
|
||||||
|
|
||||||
|
external fun getVersion(path: String): String
|
||||||
|
|
||||||
|
external fun getIcon(path: String): ByteArray
|
||||||
|
|
||||||
|
external fun getIsHomebrew(path: String): Boolean
|
||||||
|
|
||||||
|
external fun resetMetadata()
|
||||||
|
}
|
|
@ -3,17 +3,24 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.utils
|
package org.yuzu.yuzu_emu.utils
|
||||||
|
|
||||||
|
import android.view.InputDevice
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
|
|
||||||
class InputHandler {
|
object InputHandler {
|
||||||
|
private var controllerIds = getGameControllerIds()
|
||||||
|
|
||||||
fun initialize() {
|
fun initialize() {
|
||||||
// Connect first controller
|
// Connect first controller
|
||||||
NativeLibrary.onGamePadConnectEvent(getPlayerNumber(NativeLibrary.Player1Device))
|
NativeLibrary.onGamePadConnectEvent(getPlayerNumber(NativeLibrary.Player1Device))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateControllerIds() {
|
||||||
|
controllerIds = getGameControllerIds()
|
||||||
|
}
|
||||||
|
|
||||||
fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||||
val button: Int = when (event.device.vendorId) {
|
val button: Int = when (event.device.vendorId) {
|
||||||
0x045E -> getInputXboxButtonKey(event.keyCode)
|
0x045E -> getInputXboxButtonKey(event.keyCode)
|
||||||
|
@ -35,7 +42,7 @@ class InputHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
return NativeLibrary.onGamePadButtonEvent(
|
return NativeLibrary.onGamePadButtonEvent(
|
||||||
getPlayerNumber(event.device.controllerNumber),
|
getPlayerNumber(event.device.controllerNumber, event.deviceId),
|
||||||
button,
|
button,
|
||||||
action
|
action
|
||||||
)
|
)
|
||||||
|
@ -58,9 +65,14 @@ class InputHandler {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPlayerNumber(index: Int): Int {
|
private fun getPlayerNumber(index: Int, deviceId: Int = -1): Int {
|
||||||
|
var deviceIndex = index
|
||||||
|
if (deviceId != -1) {
|
||||||
|
deviceIndex = controllerIds[deviceId] ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Joycons are handled as different controllers. Find a way to merge them.
|
// TODO: Joycons are handled as different controllers. Find a way to merge them.
|
||||||
return when (index) {
|
return when (deviceIndex) {
|
||||||
2 -> NativeLibrary.Player2Device
|
2 -> NativeLibrary.Player2Device
|
||||||
3 -> NativeLibrary.Player3Device
|
3 -> NativeLibrary.Player3Device
|
||||||
4 -> NativeLibrary.Player4Device
|
4 -> NativeLibrary.Player4Device
|
||||||
|
@ -238,7 +250,7 @@ class InputHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setGenericAxisInput(event: MotionEvent, axis: Int) {
|
private fun setGenericAxisInput(event: MotionEvent, axis: Int) {
|
||||||
val playerNumber = getPlayerNumber(event.device.controllerNumber)
|
val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId)
|
||||||
|
|
||||||
when (axis) {
|
when (axis) {
|
||||||
MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
|
MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
|
||||||
|
@ -297,7 +309,7 @@ class InputHandler {
|
||||||
|
|
||||||
private fun setJoyconAxisInput(event: MotionEvent, axis: Int) {
|
private fun setJoyconAxisInput(event: MotionEvent, axis: Int) {
|
||||||
// Joycon support is half dead. Right joystick doesn't work
|
// Joycon support is half dead. Right joystick doesn't work
|
||||||
val playerNumber = getPlayerNumber(event.device.controllerNumber)
|
val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId)
|
||||||
|
|
||||||
when (axis) {
|
when (axis) {
|
||||||
MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
|
MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
|
||||||
|
@ -325,7 +337,7 @@ class InputHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setRazerAxisInput(event: MotionEvent, axis: Int) {
|
private fun setRazerAxisInput(event: MotionEvent, axis: Int) {
|
||||||
val playerNumber = getPlayerNumber(event.device.controllerNumber)
|
val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId)
|
||||||
|
|
||||||
when (axis) {
|
when (axis) {
|
||||||
MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
|
MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
|
||||||
|
@ -362,4 +374,33 @@ class InputHandler {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getGameControllerIds(): Map<Int, Int> {
|
||||||
|
val gameControllerDeviceIds = mutableMapOf<Int, Int>()
|
||||||
|
val deviceIds = InputDevice.getDeviceIds()
|
||||||
|
var controllerSlot = 1
|
||||||
|
deviceIds.forEach { deviceId ->
|
||||||
|
InputDevice.getDevice(deviceId)?.apply {
|
||||||
|
// Don't over-assign controllers
|
||||||
|
if (controllerSlot >= 8) {
|
||||||
|
return gameControllerDeviceIds
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the device has gamepad buttons, control sticks, or both.
|
||||||
|
if (sources and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD ||
|
||||||
|
sources and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK
|
||||||
|
) {
|
||||||
|
// This device is a game controller. Store its device ID.
|
||||||
|
if (deviceId and id and vendorId and productId != 0) {
|
||||||
|
// Additionally filter out devices that have no ID
|
||||||
|
gameControllerDeviceIds
|
||||||
|
.takeIf { !it.contains(deviceId) }
|
||||||
|
?.put(deviceId, controllerSlot)
|
||||||
|
controllerSlot++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gameControllerDeviceIds
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,38 +3,29 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.utils
|
package org.yuzu.yuzu_emu.utils
|
||||||
|
|
||||||
import android.util.Log
|
import android.os.Build
|
||||||
import org.yuzu.yuzu_emu.BuildConfig
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains methods that call through to [android.util.Log], but
|
|
||||||
* with the same TAG automatically provided. Also no-ops VERBOSE and DEBUG log
|
|
||||||
* levels in release builds.
|
|
||||||
*/
|
|
||||||
object Log {
|
object Log {
|
||||||
private const val TAG = "Yuzu Frontend"
|
// Tracks whether we should share the old log or the current log
|
||||||
|
var gameLaunched = false
|
||||||
|
|
||||||
fun verbose(message: String) {
|
external fun debug(message: String)
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
Log.v(TAG, message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun debug(message: String) {
|
external fun warning(message: String)
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
Log.d(TAG, message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun info(message: String) {
|
external fun info(message: String)
|
||||||
Log.i(TAG, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun warning(message: String) {
|
external fun error(message: String)
|
||||||
Log.w(TAG, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun error(message: String) {
|
external fun critical(message: String)
|
||||||
Log.e(TAG, message)
|
|
||||||
|
fun logDeviceInfo() {
|
||||||
|
info("Device Manufacturer - ${Build.MANUFACTURER}")
|
||||||
|
info("Device Model - ${Build.MODEL}")
|
||||||
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
|
||||||
|
info("SoC Manufacturer - ${Build.SOC_MANUFACTURER}")
|
||||||
|
info("SoC Model - ${Build.SOC_MODEL}")
|
||||||
|
}
|
||||||
|
info("Total System Memory - ${MemoryUtil.getDeviceRAM()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ object MemoryUtil {
|
||||||
const val Pb = Tb * 1024
|
const val Pb = Tb * 1024
|
||||||
const val Eb = Pb * 1024
|
const val Eb = Pb * 1024
|
||||||
|
|
||||||
private fun bytesToSizeUnit(size: Float): String =
|
private fun bytesToSizeUnit(size: Float, roundUp: Boolean = false): String =
|
||||||
when {
|
when {
|
||||||
size < Kb -> {
|
size < Kb -> {
|
||||||
context.getString(
|
context.getString(
|
||||||
|
@ -39,63 +39,59 @@ object MemoryUtil {
|
||||||
size < Mb -> {
|
size < Mb -> {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.memory_formatted,
|
R.string.memory_formatted,
|
||||||
(size / Kb).hundredths,
|
if (roundUp) ceil(size / Kb) else (size / Kb).hundredths,
|
||||||
context.getString(R.string.memory_kilobyte)
|
context.getString(R.string.memory_kilobyte)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
size < Gb -> {
|
size < Gb -> {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.memory_formatted,
|
R.string.memory_formatted,
|
||||||
(size / Mb).hundredths,
|
if (roundUp) ceil(size / Mb) else (size / Mb).hundredths,
|
||||||
context.getString(R.string.memory_megabyte)
|
context.getString(R.string.memory_megabyte)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
size < Tb -> {
|
size < Tb -> {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.memory_formatted,
|
R.string.memory_formatted,
|
||||||
(size / Gb).hundredths,
|
if (roundUp) ceil(size / Gb) else (size / Gb).hundredths,
|
||||||
context.getString(R.string.memory_gigabyte)
|
context.getString(R.string.memory_gigabyte)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
size < Pb -> {
|
size < Pb -> {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.memory_formatted,
|
R.string.memory_formatted,
|
||||||
(size / Tb).hundredths,
|
if (roundUp) ceil(size / Tb) else (size / Tb).hundredths,
|
||||||
context.getString(R.string.memory_terabyte)
|
context.getString(R.string.memory_terabyte)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
size < Eb -> {
|
size < Eb -> {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.memory_formatted,
|
R.string.memory_formatted,
|
||||||
(size / Pb).hundredths,
|
if (roundUp) ceil(size / Pb) else (size / Pb).hundredths,
|
||||||
context.getString(R.string.memory_petabyte)
|
context.getString(R.string.memory_petabyte)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.memory_formatted,
|
R.string.memory_formatted,
|
||||||
(size / Eb).hundredths,
|
if (roundUp) ceil(size / Eb) else (size / Eb).hundredths,
|
||||||
context.getString(R.string.memory_exabyte)
|
context.getString(R.string.memory_exabyte)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for
|
val totalMemory: Float
|
||||||
// the potential error created by memInfo.totalMem
|
|
||||||
private val totalMemory: Float
|
|
||||||
get() {
|
get() {
|
||||||
val memInfo = ActivityManager.MemoryInfo()
|
val memInfo = ActivityManager.MemoryInfo()
|
||||||
with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) {
|
with(context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) {
|
||||||
getMemoryInfo(memInfo)
|
getMemoryInfo(memInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ceil(
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
||||||
memInfo.advertisedMem.toFloat()
|
memInfo.advertisedMem.toFloat()
|
||||||
} else {
|
} else {
|
||||||
memInfo.totalMem.toFloat()
|
memInfo.totalMem.toFloat()
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isLessThan(minimum: Int, size: Float): Boolean =
|
fun isLessThan(minimum: Int, size: Float): Boolean =
|
||||||
|
@ -109,5 +105,7 @@ object MemoryUtil {
|
||||||
else -> totalMemory < Kb && totalMemory < minimum
|
else -> totalMemory < Kb && totalMemory < minimum
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory)
|
// Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for
|
||||||
|
// the potential error created by memInfo.totalMem
|
||||||
|
fun getDeviceRAM(): String = bytesToSizeUnit(totalMemory, true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,11 @@ add_library(yuzu-android SHARED
|
||||||
id_cache.cpp
|
id_cache.cpp
|
||||||
id_cache.h
|
id_cache.h
|
||||||
native.cpp
|
native.cpp
|
||||||
|
native.h
|
||||||
native_config.cpp
|
native_config.cpp
|
||||||
uisettings.cpp
|
uisettings.cpp
|
||||||
|
game_metadata.cpp
|
||||||
|
native_log.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
|
set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
|
||||||
|
|
112
src/android/app/src/main/jni/game_metadata.cpp
Normal file
112
src/android/app/src/main/jni/game_metadata.cpp
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <core/core.h>
|
||||||
|
#include <core/file_sys/patch_manager.h>
|
||||||
|
#include <core/loader/nro.h>
|
||||||
|
#include <jni.h>
|
||||||
|
#include "core/loader/loader.h"
|
||||||
|
#include "jni/android_common/android_common.h"
|
||||||
|
#include "native.h"
|
||||||
|
|
||||||
|
struct RomMetadata {
|
||||||
|
std::string title;
|
||||||
|
u64 programId;
|
||||||
|
std::string developer;
|
||||||
|
std::string version;
|
||||||
|
std::vector<u8> icon;
|
||||||
|
bool isHomebrew;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<std::string, RomMetadata> m_rom_metadata_cache;
|
||||||
|
|
||||||
|
RomMetadata CacheRomMetadata(const std::string& path) {
|
||||||
|
const auto file =
|
||||||
|
Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path);
|
||||||
|
auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0);
|
||||||
|
|
||||||
|
RomMetadata entry;
|
||||||
|
loader->ReadTitle(entry.title);
|
||||||
|
loader->ReadProgramId(entry.programId);
|
||||||
|
loader->ReadIcon(entry.icon);
|
||||||
|
|
||||||
|
const FileSys::PatchManager pm{
|
||||||
|
entry.programId, EmulationSession::GetInstance().System().GetFileSystemController(),
|
||||||
|
EmulationSession::GetInstance().System().GetContentProvider()};
|
||||||
|
const auto control = pm.GetControlMetadata();
|
||||||
|
|
||||||
|
if (control.first != nullptr) {
|
||||||
|
entry.developer = control.first->GetDeveloperName();
|
||||||
|
entry.version = control.first->GetVersionString();
|
||||||
|
} else {
|
||||||
|
FileSys::NACP nacp;
|
||||||
|
if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) {
|
||||||
|
entry.developer = nacp.GetDeveloperName();
|
||||||
|
} else {
|
||||||
|
entry.developer = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.version = "1.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loader->GetFileType() == Loader::FileType::NRO) {
|
||||||
|
auto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get());
|
||||||
|
entry.isHomebrew = loader_nro->IsHomebrew();
|
||||||
|
} else {
|
||||||
|
entry.isHomebrew = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rom_metadata_cache[path] = entry;
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
RomMetadata GetRomMetadata(const std::string& path) {
|
||||||
|
if (auto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) {
|
||||||
|
return search->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CacheRomMetadata(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj,
|
||||||
|
jstring jpath) {
|
||||||
|
return ToJString(env, GetRomMetadata(GetJString(env, jpath)).title);
|
||||||
|
}
|
||||||
|
|
||||||
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getProgramId(JNIEnv* env, jobject obj,
|
||||||
|
jstring jpath) {
|
||||||
|
return ToJString(env, std::to_string(GetRomMetadata(GetJString(env, jpath)).programId));
|
||||||
|
}
|
||||||
|
|
||||||
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, jobject obj,
|
||||||
|
jstring jpath) {
|
||||||
|
return ToJString(env, GetRomMetadata(GetJString(env, jpath)).developer);
|
||||||
|
}
|
||||||
|
|
||||||
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj,
|
||||||
|
jstring jpath) {
|
||||||
|
return ToJString(env, GetRomMetadata(GetJString(env, jpath)).version);
|
||||||
|
}
|
||||||
|
|
||||||
|
jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj,
|
||||||
|
jstring jpath) {
|
||||||
|
auto icon_data = GetRomMetadata(GetJString(env, jpath)).icon;
|
||||||
|
jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size()));
|
||||||
|
env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon),
|
||||||
|
reinterpret_cast<jbyte*>(icon_data.data()));
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, jobject obj,
|
||||||
|
jstring jpath) {
|
||||||
|
return static_cast<jboolean>(GetRomMetadata(GetJString(env, jpath)).isHomebrew);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_yuzu_yuzu_1emu_utils_GameMetadata_resetMetadata(JNIEnv* env, jobject obj) {
|
||||||
|
return m_rom_metadata_cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
|
@ -33,7 +33,6 @@
|
||||||
#include "core/crypto/key_manager.h"
|
#include "core/crypto/key_manager.h"
|
||||||
#include "core/file_sys/card_image.h"
|
#include "core/file_sys/card_image.h"
|
||||||
#include "core/file_sys/content_archive.h"
|
#include "core/file_sys/content_archive.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
|
||||||
#include "core/file_sys/submission_package.h"
|
#include "core/file_sys/submission_package.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
#include "core/file_sys/vfs_real.h"
|
#include "core/file_sys/vfs_real.h"
|
||||||
|
@ -48,63 +47,55 @@
|
||||||
#include "core/hid/emulated_controller.h"
|
#include "core/hid/emulated_controller.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
#include "core/hid/hid_types.h"
|
#include "core/hid/hid_types.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
|
||||||
#include "core/hle/service/am/applet_ae.h"
|
#include "core/hle/service/am/applet_ae.h"
|
||||||
#include "core/hle/service/am/applet_oe.h"
|
#include "core/hle/service/am/applet_oe.h"
|
||||||
#include "core/hle/service/am/applets/applets.h"
|
#include "core/hle/service/am/applets/applets.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/perf_stats.h"
|
|
||||||
#include "jni/android_common/android_common.h"
|
#include "jni/android_common/android_common.h"
|
||||||
#include "jni/applets/software_keyboard.h"
|
|
||||||
#include "jni/config.h"
|
#include "jni/config.h"
|
||||||
#include "jni/emu_window/emu_window.h"
|
|
||||||
#include "jni/id_cache.h"
|
#include "jni/id_cache.h"
|
||||||
#include "video_core/rasterizer_interface.h"
|
#include "jni/native.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
|
|
||||||
#define jconst [[maybe_unused]] const auto
|
#define jconst [[maybe_unused]] const auto
|
||||||
#define jauto [[maybe_unused]] auto
|
#define jauto [[maybe_unused]] auto
|
||||||
|
|
||||||
namespace {
|
static EmulationSession s_instance;
|
||||||
|
|
||||||
class EmulationSession final {
|
EmulationSession::EmulationSession() {
|
||||||
public:
|
|
||||||
EmulationSession() {
|
|
||||||
m_vfs = std::make_shared<FileSys::RealVfsFilesystem>();
|
m_vfs = std::make_shared<FileSys::RealVfsFilesystem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
~EmulationSession() = default;
|
EmulationSession& EmulationSession::GetInstance() {
|
||||||
|
|
||||||
static EmulationSession& GetInstance() {
|
|
||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Core::System& System() const {
|
const Core::System& EmulationSession::System() const {
|
||||||
return m_system;
|
return m_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::System& System() {
|
Core::System& EmulationSession::System() {
|
||||||
return m_system;
|
return m_system;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EmuWindow_Android& Window() const {
|
const EmuWindow_Android& EmulationSession::Window() const {
|
||||||
return *m_window;
|
return *m_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmuWindow_Android& Window() {
|
EmuWindow_Android& EmulationSession::Window() {
|
||||||
return *m_window;
|
return *m_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
ANativeWindow* NativeWindow() const {
|
ANativeWindow* EmulationSession::NativeWindow() const {
|
||||||
return m_native_window;
|
return m_native_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetNativeWindow(ANativeWindow* native_window) {
|
void EmulationSession::SetNativeWindow(ANativeWindow* native_window) {
|
||||||
m_native_window = native_window;
|
m_native_window = native_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InstallFileToNand(std::string filename, std::string file_extension) {
|
int EmulationSession::InstallFileToNand(std::string filename, std::string file_extension) {
|
||||||
jconst copy_func = [](const FileSys::VirtualFile& src, const FileSys::VirtualFile& dest,
|
jconst copy_func = [](const FileSys::VirtualFile& src, const FileSys::VirtualFile& dest,
|
||||||
std::size_t block_size) {
|
std::size_t block_size) {
|
||||||
if (src == nullptr || dest == nullptr) {
|
if (src == nullptr || dest == nullptr) {
|
||||||
|
@ -153,8 +144,8 @@ public:
|
||||||
return InstallError;
|
return InstallError;
|
||||||
}
|
}
|
||||||
|
|
||||||
jconst res = m_system.GetFileSystemController().GetUserNANDContents()->InstallEntry(
|
jconst res = m_system.GetFileSystemController().GetUserNANDContents()->InstallEntry(*nsp, true,
|
||||||
*nsp, true, copy_func);
|
copy_func);
|
||||||
|
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case FileSys::InstallResult::Success:
|
case FileSys::InstallResult::Success:
|
||||||
|
@ -168,7 +159,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir,
|
void EmulationSession::InitializeGpuDriver(const std::string& hook_lib_dir,
|
||||||
|
const std::string& custom_driver_dir,
|
||||||
const std::string& custom_driver_name,
|
const std::string& custom_driver_name,
|
||||||
const std::string& file_redirect_dir) {
|
const std::string& file_redirect_dir) {
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef ARCHITECTURE_arm64
|
||||||
|
@ -191,8 +183,7 @@ public:
|
||||||
|
|
||||||
// Try to load the system driver.
|
// Try to load the system driver.
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
handle =
|
handle = adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(),
|
||||||
adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(),
|
|
||||||
nullptr, nullptr, file_redirect_dir_, nullptr);
|
nullptr, nullptr, file_redirect_dir_, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,27 +191,27 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsRunning() const {
|
bool EmulationSession::IsRunning() const {
|
||||||
return m_is_running;
|
return m_is_running;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsPaused() const {
|
bool EmulationSession::IsPaused() const {
|
||||||
return m_is_running && m_is_paused;
|
return m_is_running && m_is_paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Core::PerfStatsResults& PerfStats() const {
|
const Core::PerfStatsResults& EmulationSession::PerfStats() const {
|
||||||
std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
|
std::scoped_lock m_perf_stats_lock(m_perf_stats_mutex);
|
||||||
return m_perf_stats;
|
return m_perf_stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceChanged() {
|
void EmulationSession::SurfaceChanged() {
|
||||||
if (!IsRunning()) {
|
if (!IsRunning()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_window->OnSurfaceChanged(m_native_window);
|
m_window->OnSurfaceChanged(m_native_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureFilesystemProvider(const std::string& filepath) {
|
void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath) {
|
||||||
const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::Mode::Read);
|
const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::Mode::Read);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
|
@ -256,15 +247,30 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::SystemResultStatus InitializeEmulation(const std::string& filepath) {
|
void EmulationSession::InitializeSystem(bool reload) {
|
||||||
|
if (!reload) {
|
||||||
|
// Initialize logging system
|
||||||
|
Common::Log::Initialize();
|
||||||
|
Common::Log::SetColorConsoleBackendEnabled(true);
|
||||||
|
Common::Log::Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize filesystem.
|
||||||
|
m_system.SetFilesystem(m_vfs);
|
||||||
|
m_system.GetUserChannel().clear();
|
||||||
|
m_manual_provider = std::make_unique<FileSys::ManualContentProvider>();
|
||||||
|
m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
|
||||||
|
m_system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
|
||||||
|
m_manual_provider.get());
|
||||||
|
m_system.GetFileSystemController().CreateFactories(*m_vfs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath) {
|
||||||
std::scoped_lock lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
|
|
||||||
// Create the render window.
|
// Create the render window.
|
||||||
m_window = std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window,
|
m_window =
|
||||||
m_vulkan_library);
|
std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window, m_vulkan_library);
|
||||||
|
|
||||||
m_system.SetFilesystem(m_vfs);
|
|
||||||
m_system.GetUserChannel().clear();
|
|
||||||
|
|
||||||
// Initialize system.
|
// Initialize system.
|
||||||
jauto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>();
|
jauto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>();
|
||||||
|
@ -286,11 +292,6 @@ public:
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initialize filesystem.
|
// Initialize filesystem.
|
||||||
m_manual_provider = std::make_unique<FileSys::ManualContentProvider>();
|
|
||||||
m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
|
|
||||||
m_system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
|
|
||||||
m_manual_provider.get());
|
|
||||||
m_system.GetFileSystemController().CreateFactories(*m_vfs);
|
|
||||||
ConfigureFilesystemProvider(filepath);
|
ConfigureFilesystemProvider(filepath);
|
||||||
|
|
||||||
// Initialize account manager
|
// Initialize account manager
|
||||||
|
@ -310,7 +311,7 @@ public:
|
||||||
return Core::SystemResultStatus::Success;
|
return Core::SystemResultStatus::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutdownEmulation() {
|
void EmulationSession::ShutdownEmulation() {
|
||||||
std::scoped_lock lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
|
|
||||||
m_is_running = false;
|
m_is_running = false;
|
||||||
|
@ -333,25 +334,25 @@ public:
|
||||||
m_window.reset();
|
m_window.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PauseEmulation() {
|
void EmulationSession::PauseEmulation() {
|
||||||
std::scoped_lock lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
m_system.Pause();
|
m_system.Pause();
|
||||||
m_is_paused = true;
|
m_is_paused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnPauseEmulation() {
|
void EmulationSession::UnPauseEmulation() {
|
||||||
std::scoped_lock lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
m_system.Run();
|
m_system.Run();
|
||||||
m_is_paused = false;
|
m_is_paused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HaltEmulation() {
|
void EmulationSession::HaltEmulation() {
|
||||||
std::scoped_lock lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
m_is_running = false;
|
m_is_running = false;
|
||||||
m_cv.notify_one();
|
m_cv.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunEmulation() {
|
void EmulationSession::RunEmulation() {
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
m_is_running = true;
|
m_is_running = true;
|
||||||
|
@ -361,8 +362,7 @@ public:
|
||||||
if (Settings::values.use_disk_shader_cache.GetValue()) {
|
if (Settings::values.use_disk_shader_cache.GetValue()) {
|
||||||
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
||||||
m_system.Renderer().ReadRasterizer()->LoadDiskResources(
|
m_system.Renderer().ReadRasterizer()->LoadDiskResources(
|
||||||
m_system.GetApplicationProcessProgramID(), std::stop_token{},
|
m_system.GetApplicationProcessProgramID(), std::stop_token{}, LoadDiskCacheProgress);
|
||||||
LoadDiskCacheProgress);
|
|
||||||
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
|
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,23 +391,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetRomTitle(const std::string& path) {
|
bool EmulationSession::IsHandheldOnly() {
|
||||||
return GetRomMetadata(path).title;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<u8> GetRomIcon(const std::string& path) {
|
|
||||||
return GetRomMetadata(path).icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetIsHomebrew(const std::string& path) {
|
|
||||||
return GetRomMetadata(path).isHomebrew;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResetRomMetadata() {
|
|
||||||
m_rom_metadata_cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsHandheldOnly() {
|
|
||||||
jconst npad_style_set = m_system.HIDCore().GetSupportedStyleTag();
|
jconst npad_style_set = m_system.HIDCore().GetSupportedStyleTag();
|
||||||
|
|
||||||
if (npad_style_set.fullkey == 1) {
|
if (npad_style_set.fullkey == 1) {
|
||||||
|
@ -421,18 +405,17 @@ public:
|
||||||
return !Settings::IsDockedMode();
|
return !Settings::IsDockedMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDeviceType([[maybe_unused]] int index, int type) {
|
void EmulationSession::SetDeviceType([[maybe_unused]] int index, int type) {
|
||||||
jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||||
controller->SetNpadStyleIndex(static_cast<Core::HID::NpadStyleIndex>(type));
|
controller->SetNpadStyleIndex(static_cast<Core::HID::NpadStyleIndex>(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnGamepadConnectEvent([[maybe_unused]] int index) {
|
void EmulationSession::OnGamepadConnectEvent([[maybe_unused]] int index) {
|
||||||
jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||||
|
|
||||||
// Ensure that player1 is configured correctly and handheld disconnected
|
// Ensure that player1 is configured correctly and handheld disconnected
|
||||||
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Player1) {
|
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Player1) {
|
||||||
jauto handheld =
|
jauto handheld = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
|
||||||
|
|
||||||
if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) {
|
if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) {
|
||||||
handheld->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController);
|
handheld->SetNpadStyleIndex(Core::HID::NpadStyleIndex::ProController);
|
||||||
|
@ -443,8 +426,7 @@ public:
|
||||||
|
|
||||||
// Ensure that handheld is configured correctly and player 1 disconnected
|
// Ensure that handheld is configured correctly and player 1 disconnected
|
||||||
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Handheld) {
|
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Handheld) {
|
||||||
jauto player1 =
|
jauto player1 = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||||
m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
|
||||||
|
|
||||||
if (controller->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::Handheld) {
|
if (controller->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::Handheld) {
|
||||||
player1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
|
player1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
|
||||||
|
@ -458,110 +440,35 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnGamepadDisconnectEvent([[maybe_unused]] int index) {
|
void EmulationSession::OnGamepadDisconnectEvent([[maybe_unused]] int index) {
|
||||||
jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||||
controller->Disconnect();
|
controller->Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard() {
|
SoftwareKeyboard::AndroidKeyboard* EmulationSession::SoftwareKeyboard() {
|
||||||
return m_software_keyboard;
|
return m_software_keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
void EmulationSession::LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress,
|
||||||
struct RomMetadata {
|
int max) {
|
||||||
std::string title;
|
|
||||||
std::vector<u8> icon;
|
|
||||||
bool isHomebrew;
|
|
||||||
};
|
|
||||||
|
|
||||||
RomMetadata GetRomMetadata(const std::string& path) {
|
|
||||||
if (jauto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) {
|
|
||||||
return search->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CacheRomMetadata(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
RomMetadata CacheRomMetadata(const std::string& path) {
|
|
||||||
jconst file = Core::GetGameFileFromPath(m_vfs, path);
|
|
||||||
jauto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0);
|
|
||||||
|
|
||||||
RomMetadata entry;
|
|
||||||
loader->ReadTitle(entry.title);
|
|
||||||
loader->ReadIcon(entry.icon);
|
|
||||||
if (loader->GetFileType() == Loader::FileType::NRO) {
|
|
||||||
jauto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get());
|
|
||||||
entry.isHomebrew = loader_nro->IsHomebrew();
|
|
||||||
} else {
|
|
||||||
entry.isHomebrew = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rom_metadata_cache[path] = entry;
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max) {
|
|
||||||
JNIEnv* env = IDCache::GetEnvForThread();
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
env->CallStaticVoidMethod(IDCache::GetDiskCacheProgressClass(),
|
env->CallStaticVoidMethod(IDCache::GetDiskCacheProgressClass(),
|
||||||
IDCache::GetDiskCacheLoadProgress(), static_cast<jint>(stage),
|
IDCache::GetDiskCacheLoadProgress(), static_cast<jint>(stage),
|
||||||
static_cast<jint>(progress), static_cast<jint>(max));
|
static_cast<jint>(progress), static_cast<jint>(max));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnEmulationStarted() {
|
void EmulationSession::OnEmulationStarted() {
|
||||||
JNIEnv* env = IDCache::GetEnvForThread();
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(),
|
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnEmulationStarted());
|
||||||
IDCache::GetOnEmulationStarted());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnEmulationStopped(Core::SystemResultStatus result) {
|
void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
|
||||||
JNIEnv* env = IDCache::GetEnvForThread();
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(),
|
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnEmulationStopped(),
|
||||||
IDCache::GetOnEmulationStopped(), static_cast<jint>(result));
|
static_cast<jint>(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
static EmulationSession s_instance;
|
|
||||||
|
|
||||||
// Frontend management
|
|
||||||
std::unordered_map<std::string, RomMetadata> m_rom_metadata_cache;
|
|
||||||
|
|
||||||
// Window management
|
|
||||||
std::unique_ptr<EmuWindow_Android> m_window;
|
|
||||||
ANativeWindow* m_native_window{};
|
|
||||||
|
|
||||||
// Core emulation
|
|
||||||
Core::System m_system;
|
|
||||||
InputCommon::InputSubsystem m_input_subsystem;
|
|
||||||
Common::DetachedTasks m_detached_tasks;
|
|
||||||
Core::PerfStatsResults m_perf_stats{};
|
|
||||||
std::shared_ptr<FileSys::VfsFilesystem> m_vfs;
|
|
||||||
Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
|
|
||||||
std::atomic<bool> m_is_running = false;
|
|
||||||
std::atomic<bool> m_is_paused = false;
|
|
||||||
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
|
|
||||||
std::unique_ptr<Service::Account::ProfileManager> m_profile_manager;
|
|
||||||
std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
|
|
||||||
|
|
||||||
// GPU driver parameters
|
|
||||||
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
|
|
||||||
|
|
||||||
// Synchronization
|
|
||||||
std::condition_variable_any m_cv;
|
|
||||||
mutable std::mutex m_perf_stats_mutex;
|
|
||||||
mutable std::mutex m_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*static*/ EmulationSession EmulationSession::s_instance;
|
|
||||||
|
|
||||||
} // Anonymous namespace
|
|
||||||
|
|
||||||
static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
|
static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
|
||||||
Common::Log::Initialize();
|
|
||||||
Common::Log::SetColorConsoleBackendEnabled(true);
|
|
||||||
Common::Log::Start();
|
|
||||||
|
|
||||||
MicroProfileOnThreadCreate("EmuThread");
|
MicroProfileOnThreadCreate("EmuThread");
|
||||||
SCOPE_EXIT({ MicroProfileShutdown(); });
|
SCOPE_EXIT({ MicroProfileShutdown(); });
|
||||||
|
|
||||||
|
@ -657,10 +564,6 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_stopEmulation(JNIEnv* env, jclass cla
|
||||||
EmulationSession::GetInstance().HaltEmulation();
|
EmulationSession::GetInstance().HaltEmulation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_resetRomMetadata(JNIEnv* env, jclass clazz) {
|
|
||||||
EmulationSession::GetInstance().ResetRomMetadata();
|
|
||||||
}
|
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isRunning(JNIEnv* env, jclass clazz) {
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isRunning(JNIEnv* env, jclass clazz) {
|
||||||
return static_cast<jboolean>(EmulationSession::GetInstance().IsRunning());
|
return static_cast<jboolean>(EmulationSession::GetInstance().IsRunning());
|
||||||
}
|
}
|
||||||
|
@ -766,52 +669,16 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchReleased(JNIEnv* env, jclass c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jbyteArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getIcon(JNIEnv* env, jclass clazz,
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass clazz,
|
||||||
jstring j_filename) {
|
jboolean reload) {
|
||||||
jauto icon_data = EmulationSession::GetInstance().GetRomIcon(GetJString(env, j_filename));
|
|
||||||
jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size()));
|
|
||||||
env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon),
|
|
||||||
reinterpret_cast<jbyte*>(icon_data.data()));
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getTitle(JNIEnv* env, jclass clazz,
|
|
||||||
jstring j_filename) {
|
|
||||||
jauto title = EmulationSession::GetInstance().GetRomTitle(GetJString(env, j_filename));
|
|
||||||
return env->NewStringUTF(title.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getDescription(JNIEnv* env, jclass clazz,
|
|
||||||
jstring j_filename) {
|
|
||||||
return j_filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getGameId(JNIEnv* env, jclass clazz,
|
|
||||||
jstring j_filename) {
|
|
||||||
return j_filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getRegions(JNIEnv* env, jclass clazz,
|
|
||||||
jstring j_filename) {
|
|
||||||
return env->NewStringUTF("");
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCompany(JNIEnv* env, jclass clazz,
|
|
||||||
jstring j_filename) {
|
|
||||||
return env->NewStringUTF("");
|
|
||||||
}
|
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isHomebrew(JNIEnv* env, jclass clazz,
|
|
||||||
jstring j_filename) {
|
|
||||||
return EmulationSession::GetInstance().GetIsHomebrew(GetJString(env, j_filename));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmulation(JNIEnv* env, jclass clazz) {
|
|
||||||
// Create the default config.ini.
|
// Create the default config.ini.
|
||||||
Config{};
|
Config{};
|
||||||
// Initialize the emulated system.
|
// Initialize the emulated system.
|
||||||
|
if (!reload) {
|
||||||
EmulationSession::GetInstance().System().Initialize();
|
EmulationSession::GetInstance().System().Initialize();
|
||||||
}
|
}
|
||||||
|
EmulationSession::GetInstance().InitializeSystem(reload);
|
||||||
|
}
|
||||||
|
|
||||||
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass clazz) {
|
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass clazz) {
|
||||||
return {};
|
return {};
|
||||||
|
@ -898,4 +765,49 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmptyUserDirectory(JNIEnv*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletLaunchPath(JNIEnv* env, jclass clazz,
|
||||||
|
jlong jid) {
|
||||||
|
auto bis_system =
|
||||||
|
EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
|
||||||
|
if (!bis_system) {
|
||||||
|
return ToJString(env, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto applet_nca =
|
||||||
|
bis_system->GetEntry(static_cast<u64>(jid), FileSys::ContentRecordType::Program);
|
||||||
|
if (!applet_nca) {
|
||||||
|
return ToJString(env, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ToJString(env, applet_nca->GetFullPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCurrentAppletId(JNIEnv* env, jclass clazz,
|
||||||
|
jint jappletId) {
|
||||||
|
EmulationSession::GetInstance().System().GetAppletManager().SetCurrentAppletId(
|
||||||
|
static_cast<Service::AM::Applets::AppletId>(jappletId));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCabinetMode(JNIEnv* env, jclass clazz,
|
||||||
|
jint jcabinetMode) {
|
||||||
|
EmulationSession::GetInstance().System().GetAppletManager().SetCabinetMode(
|
||||||
|
static_cast<Service::NFP::CabinetMode>(jcabinetMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env, jclass clazz) {
|
||||||
|
auto bis_system =
|
||||||
|
EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
|
||||||
|
if (!bis_system) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query an applet to see if it's available
|
||||||
|
auto applet_nca =
|
||||||
|
bis_system->GetEntry(0x010000000000100Dull, FileSys::ContentRecordType::Program);
|
||||||
|
if (!applet_nca) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
85
src/android/app/src/main/jni/native.h
Normal file
85
src/android/app/src/main/jni/native.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <android/native_window_jni.h>
|
||||||
|
#include "common/detached_tasks.h"
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/file_sys/registered_cache.h"
|
||||||
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
|
#include "core/perf_stats.h"
|
||||||
|
#include "jni/applets/software_keyboard.h"
|
||||||
|
#include "jni/emu_window/emu_window.h"
|
||||||
|
#include "video_core/rasterizer_interface.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class EmulationSession final {
|
||||||
|
public:
|
||||||
|
explicit EmulationSession();
|
||||||
|
~EmulationSession() = default;
|
||||||
|
|
||||||
|
static EmulationSession& GetInstance();
|
||||||
|
const Core::System& System() const;
|
||||||
|
Core::System& System();
|
||||||
|
|
||||||
|
const EmuWindow_Android& Window() const;
|
||||||
|
EmuWindow_Android& Window();
|
||||||
|
ANativeWindow* NativeWindow() const;
|
||||||
|
void SetNativeWindow(ANativeWindow* native_window);
|
||||||
|
void SurfaceChanged();
|
||||||
|
|
||||||
|
int InstallFileToNand(std::string filename, std::string file_extension);
|
||||||
|
void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir,
|
||||||
|
const std::string& custom_driver_name,
|
||||||
|
const std::string& file_redirect_dir);
|
||||||
|
|
||||||
|
bool IsRunning() const;
|
||||||
|
bool IsPaused() const;
|
||||||
|
void PauseEmulation();
|
||||||
|
void UnPauseEmulation();
|
||||||
|
void HaltEmulation();
|
||||||
|
void RunEmulation();
|
||||||
|
void ShutdownEmulation();
|
||||||
|
|
||||||
|
const Core::PerfStatsResults& PerfStats() const;
|
||||||
|
void ConfigureFilesystemProvider(const std::string& filepath);
|
||||||
|
void InitializeSystem(bool reload);
|
||||||
|
Core::SystemResultStatus InitializeEmulation(const std::string& filepath);
|
||||||
|
|
||||||
|
bool IsHandheldOnly();
|
||||||
|
void SetDeviceType([[maybe_unused]] int index, int type);
|
||||||
|
void OnGamepadConnectEvent([[maybe_unused]] int index);
|
||||||
|
void OnGamepadDisconnectEvent([[maybe_unused]] int index);
|
||||||
|
SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max);
|
||||||
|
static void OnEmulationStarted();
|
||||||
|
static void OnEmulationStopped(Core::SystemResultStatus result);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Window management
|
||||||
|
std::unique_ptr<EmuWindow_Android> m_window;
|
||||||
|
ANativeWindow* m_native_window{};
|
||||||
|
|
||||||
|
// Core emulation
|
||||||
|
Core::System m_system;
|
||||||
|
InputCommon::InputSubsystem m_input_subsystem;
|
||||||
|
Common::DetachedTasks m_detached_tasks;
|
||||||
|
Core::PerfStatsResults m_perf_stats{};
|
||||||
|
std::shared_ptr<FileSys::VfsFilesystem> m_vfs;
|
||||||
|
Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
|
||||||
|
std::atomic<bool> m_is_running = false;
|
||||||
|
std::atomic<bool> m_is_paused = false;
|
||||||
|
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
|
||||||
|
std::unique_ptr<Service::Account::ProfileManager> m_profile_manager;
|
||||||
|
std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
|
||||||
|
|
||||||
|
// GPU driver parameters
|
||||||
|
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
|
||||||
|
|
||||||
|
// Synchronization
|
||||||
|
std::condition_variable_any m_cv;
|
||||||
|
mutable std::mutex m_perf_stats_mutex;
|
||||||
|
mutable std::mutex m_mutex;
|
||||||
|
};
|
31
src/android/app/src/main/jni/native_log.cpp
Normal file
31
src/android/app/src/main/jni/native_log.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <common/logging/log.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#include "android_common/android_common.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void Java_org_yuzu_yuzu_1emu_utils_Log_debug(JNIEnv* env, jobject obj, jstring jmessage) {
|
||||||
|
LOG_DEBUG(Frontend, "{}", GetJString(env, jmessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_yuzu_yuzu_1emu_utils_Log_warning(JNIEnv* env, jobject obj, jstring jmessage) {
|
||||||
|
LOG_WARNING(Frontend, "{}", GetJString(env, jmessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_yuzu_yuzu_1emu_utils_Log_info(JNIEnv* env, jobject obj, jstring jmessage) {
|
||||||
|
LOG_INFO(Frontend, "{}", GetJString(env, jmessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_yuzu_yuzu_1emu_utils_Log_error(JNIEnv* env, jobject obj, jstring jmessage) {
|
||||||
|
LOG_ERROR(Frontend, "{}", GetJString(env, jmessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Java_org_yuzu_yuzu_1emu_utils_Log_critical(JNIEnv* env, jobject obj, jstring jmessage) {
|
||||||
|
LOG_CRITICAL(Frontend, "{}", GetJString(env, jmessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
9
src/android/app/src/main/res/drawable/ic_album.xml
Normal file
9
src/android/app/src/main/res/drawable/ic_album.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
|
||||||
|
</vector>
|
9
src/android/app/src/main/res/drawable/ic_applet.xml
Normal file
9
src/android/app/src/main/res/drawable/ic_applet.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M17,16l-4,-4V8.82C14.16,8.4 15,7.3 15,6c0,-1.66 -1.34,-3 -3,-3S9,4.34 9,6c0,1.3 0.84,2.4 2,2.82V12l-4,4H3v5h5v-3.05l4,-4.2 4,4.2V21h5v-5h-4z" />
|
||||||
|
</vector>
|
9
src/android/app/src/main/res/drawable/ic_edit.xml
Normal file
9
src/android/app/src/main/res/drawable/ic_edit.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
|
||||||
|
</vector>
|
18
src/android/app/src/main/res/drawable/ic_mii.xml
Normal file
18
src/android/app/src/main/res/drawable/ic_mii.xml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M9,13m-1.25,0a1.25,1.25 0,1 1,2.5 0a1.25,1.25 0,1 1,-2.5 0" />
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M20.77,8.58l-0.92,2.01c0.09,0.46 0.15,0.93 0.15,1.41 0,4.41 -3.59,8 -8,8s-8,-3.59 -8,-8c0,-0.05 0.01,-0.1 0,-0.14 2.6,-0.98 4.69,-2.99 5.74,-5.55C11.58,8.56 14.37,10 17.5,10c0.45,0 0.89,-0.04 1.33,-0.1l-0.6,-1.32 -0.88,-1.93 -1.93,-0.88 -2.79,-1.27 2.79,-1.27 0.71,-0.32C14.87,2.33 13.47,2 12,2 6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10c0,-1.47 -0.33,-2.87 -0.9,-4.13l-0.33,0.71z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M15,13m-1.25,0a1.25,1.25 0,1 1,2.5 0a1.25,1.25 0,1 1,-2.5 0" />
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M20.6,5.6L19.5,8l-1.1,-2.4L16,4.5l2.4,-1.1L19.5,1l1.1,2.4L23,4.5z" />
|
||||||
|
</vector>
|
9
src/android/app/src/main/res/drawable/ic_refresh.xml
Normal file
9
src/android/app/src/main/res/drawable/ic_refresh.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z" />
|
||||||
|
</vector>
|
9
src/android/app/src/main/res/drawable/ic_restore.xml
Normal file
9
src/android/app/src/main/res/drawable/ic_restore.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorControlNormal"
|
||||||
|
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z" />
|
||||||
|
</vector>
|
57
src/android/app/src/main/res/layout/card_applet_option.xml
Normal file
57
src/android/app/src/main/res/layout/card_applet_option.xml
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
style="?attr/materialCardViewOutlinedStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginVertical="12dp"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:padding="24dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
app:tint="?attr/colorOnSurface" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_gravity="center_vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
style="@style/TextAppearance.Material3.TitleMedium"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
tools:text="@string/applets" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/description"
|
||||||
|
style="@style/TextAppearance.Material3.BodyMedium"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
tools:text="@string/applets_description" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
|
@ -1,63 +1,54 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
style="?attr/materialCardViewElevatedStyle"
|
|
||||||
android:id="@+id/card_game"
|
android:id="@+id/card_game"
|
||||||
|
style="?attr/materialCardViewElevatedStyle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:transitionName="card_game"
|
android:transitionName="card_game"
|
||||||
android:layout_gravity="center"
|
app:cardCornerRadius="4dp"
|
||||||
app:cardElevation="0dp"
|
app:cardElevation="0dp">
|
||||||
app:cardCornerRadius="12dp">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="6dp">
|
android:padding="6dp">
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
style="?attr/materialCardViewElevatedStyle"
|
android:id="@+id/image_game_screen"
|
||||||
android:id="@+id/card_game_art"
|
|
||||||
android:layout_width="150dp"
|
android:layout_width="150dp"
|
||||||
android:layout_height="150dp"
|
android:layout_height="150dp"
|
||||||
app:cardCornerRadius="4dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.ExtraSmall"
|
||||||
<ImageView
|
|
||||||
android:id="@+id/image_game_screen"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:src="@drawable/default_icon" />
|
tools:src="@drawable/default_icon" />
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
style="@style/TextAppearance.Material3.TitleMedium"
|
|
||||||
android:id="@+id/text_game_title"
|
android:id="@+id/text_game_title"
|
||||||
|
style="@style/TextAppearance.Material3.TitleMedium"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:ellipsize="none"
|
||||||
|
android:marqueeRepeatLimit="marquee_forever"
|
||||||
|
android:requiresFadingEdge="horizontal"
|
||||||
|
android:singleLine="true"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:singleLine="true"
|
app:layout_constraintEnd_toEndOf="@+id/image_game_screen"
|
||||||
android:marqueeRepeatLimit="marquee_forever"
|
app:layout_constraintStart_toStartOf="@+id/image_game_screen"
|
||||||
android:ellipsize="none"
|
app:layout_constraintTop_toBottomOf="@+id/image_game_screen"
|
||||||
android:requiresFadingEdge="horizontal"
|
|
||||||
app:layout_constraintEnd_toEndOf="@+id/card_game_art"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/card_game_art"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/card_game_art"
|
|
||||||
tools:text="The Legend of Zelda: Skyward Sword" />
|
tools:text="The Legend of Zelda: Skyward Sword" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/option_layout"
|
android:id="@+id/option_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/option_icon"
|
android:id="@+id/option_icon"
|
||||||
|
|
15
src/android/app/src/main/res/layout/dialog_list.xml
Normal file
15
src/android/app/src/main/res/layout/dialog_list.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/dialog_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:fadeScrollbars="false"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:scrollbars="vertical" />
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
30
src/android/app/src/main/res/layout/dialog_list_item.xml
Normal file
30
src/android/app/src/main/res/layout/dialog_list_item.xml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="24dp"
|
||||||
|
android:paddingVertical="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
tools:src="@drawable/ic_nfc" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
style="@style/TextAppearance.Material3.BodyMedium"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_gravity="center_vertical|start"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
tools:text="List option" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/coordinator_applets"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar_applets"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar_applets"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:navigationIcon="@drawable/ic_back"
|
||||||
|
app:title="@string/applets" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/list_applets"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -25,6 +25,9 @@
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_homeSettingsFragment_to_driverManagerFragment"
|
android:id="@+id/action_homeSettingsFragment_to_driverManagerFragment"
|
||||||
app:destination="@id/driverManagerFragment" />
|
app:destination="@id/driverManagerFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_homeSettingsFragment_to_appletLauncherFragment"
|
||||||
|
app:destination="@id/appletLauncherFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
|
@ -102,5 +105,17 @@
|
||||||
android:id="@+id/driverManagerFragment"
|
android:id="@+id/driverManagerFragment"
|
||||||
android:name="org.yuzu.yuzu_emu.fragments.DriverManagerFragment"
|
android:name="org.yuzu.yuzu_emu.fragments.DriverManagerFragment"
|
||||||
android:label="DriverManagerFragment" />
|
android:label="DriverManagerFragment" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/appletLauncherFragment"
|
||||||
|
android:name="org.yuzu.yuzu_emu.fragments.AppletLauncherFragment"
|
||||||
|
android:label="AppletLauncherFragment" >
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_appletLauncherFragment_to_cabinetLauncherDialogFragment"
|
||||||
|
app:destination="@id/cabinetLauncherDialogFragment" />
|
||||||
|
</fragment>
|
||||||
|
<dialog
|
||||||
|
android:id="@+id/cabinetLauncherDialogFragment"
|
||||||
|
android:name="org.yuzu.yuzu_emu.fragments.CabinetLauncherDialogFragment"
|
||||||
|
android:label="CabinetLauncherDialogFragment" />
|
||||||
|
|
||||||
</navigation>
|
</navigation>
|
||||||
|
|
1
src/android/app/src/main/res/resources.properties
Normal file
1
src/android/app/src/main/res/resources.properties
Normal file
|
@ -0,0 +1 @@
|
||||||
|
unqualifiedResLocale=en-US
|
385
src/android/app/src/main/res/values-ar/strings.xml
Normal file
385
src/android/app/src/main/res/values-ar/strings.xml
Normal file
|
@ -0,0 +1,385 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||||
|
|
||||||
|
<string name="emulation_notification_channel_name">المحاكي نشط</string>
|
||||||
|
<string name="emulation_notification_channel_description">اظهار اشعار دائم عندما يكون المحاكي نشطاً</string>
|
||||||
|
<string name="emulation_notification_running">يوزو يعمل</string>
|
||||||
|
<string name="notice_notification_channel_name">الإشعارات والأخطاء</string>
|
||||||
|
<string name="notice_notification_channel_description">اظهار اشعار عند حصول اي مشكلة.</string>
|
||||||
|
<string name="notification_permission_not_granted">لم يتم منح إذن الإشعار</string>
|
||||||
|
|
||||||
|
<!-- Setup strings -->
|
||||||
|
<string name="welcome">مرحبًا</string>
|
||||||
|
<string name="welcome_description">والانتقال إلى المحاكاة <b>يوزو</b> تعرف على كيفية إعداد.</string>
|
||||||
|
<string name="get_started">لنبدأ</string>
|
||||||
|
<string name="keys">المفاتيح</string>
|
||||||
|
<string name="keys_description">اختر ملف <b>prod.keys</b> من الزر ادناه</string>
|
||||||
|
<string name="select_keys">إختيار المفاتيح</string>
|
||||||
|
<string name="games">الألعاب</string>
|
||||||
|
<string name="games_description">اختر مجلد <b>العابك</b> من الزر ادناه.</string>
|
||||||
|
<string name="done">إنهاء</string>
|
||||||
|
<string name="done_description">كل شيء جاهز./n استمتع بألعابك!</string>
|
||||||
|
<string name="text_continue">استمر</string>
|
||||||
|
<string name="next">التالي</string>
|
||||||
|
<string name="back">عودة</string>
|
||||||
|
<string name="add_games">إضافة ألعاب</string>
|
||||||
|
<string name="add_games_description">إختار مجلد ألعابك</string>
|
||||||
|
<string name="step_complete">مكتمل</string>
|
||||||
|
|
||||||
|
<!-- Home strings -->
|
||||||
|
<string name="home_games">الألعاب</string>
|
||||||
|
<string name="home_search">البحث</string>
|
||||||
|
<string name="home_settings">الإعدادات</string>
|
||||||
|
<string name="empty_gamelist">لم يتم العثور على ملفات او لم يتم تحديد مسار العاب.</string>
|
||||||
|
<string name="search_and_filter_games">بحث وتصفية الألعاب</string>
|
||||||
|
<string name="select_games_folder">تحديد مجلد الألعاب</string>
|
||||||
|
<string name="select_games_folder_description">يسمح لـ يوزو بملء قائمة الألعاب</string>
|
||||||
|
<string name="add_games_warning">تخطُ اختيار مجلد الالعاب؟</string>
|
||||||
|
<string name="add_games_warning_description">لن يتم عرض الألعاب في قائمة الألعاب إذا لم يتم تحديد مجلد</string>
|
||||||
|
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
|
||||||
|
<string name="home_search_games">البحث عن ألعاب</string>
|
||||||
|
<string name="search_settings">إعدادات البحث</string>
|
||||||
|
<string name="games_dir_selected">تم تحديد مجلد الألعاب</string>
|
||||||
|
<string name="install_prod_keys">تثبيت prod.keys</string>
|
||||||
|
<string name="install_prod_keys_description">مطلوب لفك تشفير ألعاب البيع بالتجزئة</string>
|
||||||
|
<string name="install_prod_keys_warning">تخطي إضافة المفاتيح؟</string>
|
||||||
|
<string name="install_prod_keys_warning_description">مطلوب مفاتيح صالحة لمحاكاة ألعاب البيع بالتجزئة. ستعمل تطبيقات البيرة المنزلية فقط إذا تابعت</string>
|
||||||
|
<string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
|
||||||
|
<string name="notifications">التنبيهات</string>
|
||||||
|
<string name="notifications_description">امنح إذن الإشعار باستخدام الزر أدناه</string>
|
||||||
|
<string name="give_permission">منح الإذن</string>
|
||||||
|
<string name="notification_warning">تخطي منح إذن الإشعارات؟</string>
|
||||||
|
<string name="notification_warning_description">لن يتمكن يوزو من إشعارك بالمعلومات المهمة</string>
|
||||||
|
<string name="permission_denied">تم رفض الإذن</string>
|
||||||
|
<string name="permission_denied_description">لقد رفضت هذا الإذن عدة مرات ويتعين عليك الآن منحه يدويًا في إعدادات النظام</string>
|
||||||
|
<string name="about">حول</string>
|
||||||
|
<string name="about_description">بناء الإصدار، والاعتمادات، وأكثر من ذلك</string>
|
||||||
|
<string name="warning_help">مساعدة</string>
|
||||||
|
<string name="warning_skip">تخطي</string>
|
||||||
|
<string name="warning_cancel">إلغاء</string>
|
||||||
|
<string name="install_amiibo_keys">تثبيت مفاتيح أميبو</string>
|
||||||
|
<string name="install_amiibo_keys_description">مطلوب لاستخدام أميبو في اللعبة</string>
|
||||||
|
<string name="invalid_keys_file">تم تحديد ملف مفاتيح غير صالح</string>
|
||||||
|
<string name="install_keys_success">تم تثبيت المفاتيح بنجاح</string>
|
||||||
|
<string name="reading_keys_failure">خطأ في قراءة مفاتيح التشفير</string>
|
||||||
|
<string name="invalid_keys_error">مفاتيح التشفير غير صالحة</string>
|
||||||
|
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
|
||||||
|
<string name="install_keys_failure_description">الملف المحدد غير صحيح أو تالف. يرجى إعادة المفاتيح الخاصة بك</string>
|
||||||
|
<string name="install_gpu_driver">GPU تثبيت برنامج تشغيل</string>
|
||||||
|
<string name="install_gpu_driver_description">قم بتثبيت برامج تشغيل بديلة للحصول على أداء أو دقة أفضل</string>
|
||||||
|
<string name="advanced_settings">إعدادات متقدمة</string>
|
||||||
|
<string name="advanced_settings_game">إعدادات متقدمة: %1$s</string>
|
||||||
|
<string name="settings_description">تكوين إعدادات المحاكي</string>
|
||||||
|
<string name="search_recently_played">لعبت مؤخرا</string>
|
||||||
|
<string name="search_recently_added">أضيف مؤخرا</string>
|
||||||
|
<string name="search_retail">بيع بالتجزئة</string>
|
||||||
|
<string name="search_homebrew">البيرة المنزلية</string>
|
||||||
|
<string name="open_user_folder">فتح مجلد يوزو</string>
|
||||||
|
<string name="open_user_folder_description">إدارة ملفات يوزو الداخلية</string>
|
||||||
|
<string name="theme_and_color_description">تعديل مظهر التطبيق</string>
|
||||||
|
<string name="no_file_manager">لم يتم العثور على مدير الملفات</string>
|
||||||
|
<string name="notification_no_directory_link">لا يمكن فتح مجلد يوزو</string>
|
||||||
|
<string name="notification_no_directory_link_description">الرجاء تحديد موقع مجلد المستخدم باستخدام اللوحة الجانبية لمدير الملفات يدويًا</string>
|
||||||
|
<string name="manage_save_data">إدارة حفظ البيانات</string>
|
||||||
|
<string name="manage_save_data_description">حفظ البيانات التي تم العثور عليها. يرجى اختيار أحد الخيارات التالية</string>
|
||||||
|
<string name="import_export_saves_description">استيراد أو تصدير ملفات الحفظ</string>
|
||||||
|
<string name="save_file_imported_success">تم الاستيراد بنجاح</string>
|
||||||
|
<string name="save_file_invalid_zip_structure">بنية مجلد الحفظ غير صالحة</string>
|
||||||
|
<string name="save_file_invalid_zip_structure_description">يجب أن يكون اسم المجلد الفرعي الأول هو معرف عنوان اللعبة.</string>
|
||||||
|
<string name="import_saves">استيراد</string>
|
||||||
|
<string name="export_saves">تصدير</string>
|
||||||
|
<string name="install_firmware">تثبيت البرامج الثابتة</string>
|
||||||
|
<string name="firmware_installing">تثبيت البرامج الثابتة</string>
|
||||||
|
<string name="firmware_installed_success">تم تثبيت البرامج الثابتة بنجاح</string>
|
||||||
|
<string name="firmware_installed_failure">فشل تثبيت البرامج الثابتة</string>
|
||||||
|
<string name="share_log">مشاركة سجلات التصحيح</string>
|
||||||
|
<string name="share_log_description">مشاركة ملف سجل يوزو لتصحيح المشكلات</string>
|
||||||
|
<string name="share_log_missing">لم يتم العثور على ملف السجل</string>
|
||||||
|
<string name="install_game_content">تثبيت محتوى اللعبة</string>
|
||||||
|
<string name="install_game_content_description">DLC قم بتثبيت تحديثات اللعبة أو</string>
|
||||||
|
<string name="installing_game_content">جارٍ تثبيت المحتوى</string>
|
||||||
|
<string name="install_game_content_failure_base">لا يُسمح بتثبيت الألعاب الأساسية لتجنب التعارضات المحتملة.</string>
|
||||||
|
<string name="install_game_content_success_install">%1$d تم التثبيت بنجاح</string>
|
||||||
|
<string name="install_game_content_success_overwrite">%1$d تمت الكتابة فوقه بنجاح</string>
|
||||||
|
<string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
|
||||||
|
<string name="custom_driver_not_supported">برامج التشغيل المخصصة غير مدعومة</string>
|
||||||
|
<string name="custom_driver_not_supported_description">تحميل برنامج التشغيل المخصص غير معتمد حاليًا لهذا الجهاز.\nحدد هذا الخيار مرة أخرى في المستقبل لمعرفة ما إذا تمت إضافة الدعم!</string>
|
||||||
|
<string name="manage_yuzu_data">إدارة بيانات يوزو</string>
|
||||||
|
<string name="manage_yuzu_data_description">استيراد/تصدير البرامج الثابتة والمفاتيح وبيانات المستخدم والمزيد!</string>
|
||||||
|
<string name="share_save_file">مشاركة ملف الحفظ</string>
|
||||||
|
<string name="export_save_failed">فشل تصدير الحفظ</string>
|
||||||
|
|
||||||
|
<string name="copied_to_clipboard">نسخ إلى الحافظة</string>
|
||||||
|
<string name="about_app_description">محاكي سويتش مفتوح المصدر</string>
|
||||||
|
<string name="contributors">المساهمين</string>
|
||||||
|
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
|
||||||
|
<string name="licenses_description">المشاريع التي تجعل تطبيق يوزو لنظام أندرويد ممكنًا</string>
|
||||||
|
<string name="build">البناء</string>
|
||||||
|
<string name="user_data">بيانات المستخدم</string>
|
||||||
|
<string name="exporting_user_data">جارٍ تصدير بيانات المستخدم</string>
|
||||||
|
<string name="importing_user_data">جارٍ استيراد بيانات المستخدم</string>
|
||||||
|
<string name="import_user_data">استيراد بيانات المستخدم</string>
|
||||||
|
<string name="invalid_yuzu_backup">نسخة احتياطية يوزو غير صالحة</string>
|
||||||
|
<string name="user_data_export_success">تم تصدير بيانات المستخدم بنجاح</string>
|
||||||
|
<string name="user_data_import_success">تم استيراد بيانات المستخدم بنجاح</string>
|
||||||
|
<string name="user_data_export_cancelled">تم إلغاء التصدير</string>
|
||||||
|
<string name="support_link">https://discord.gg/u77vRWY</string>
|
||||||
|
<string name="website_link">https://yuzu-emu.org/</string>
|
||||||
|
<string name="github_link">https://github.com/yuzu-emu</string>
|
||||||
|
|
||||||
|
<!-- Early access upgrade strings -->
|
||||||
|
<string name="early_access">الوصول المبكر</string>
|
||||||
|
<string name="get_early_access">احصل على الوصول المبكر</string>
|
||||||
|
<string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
|
||||||
|
<string name="get_early_access_description">الميزات المتطورة، والوصول المبكر إلى التحديثات، وأكثر من ذلك</string>
|
||||||
|
<string name="early_access_benefits">مزايا الوصول المبكر</string>
|
||||||
|
<string name="cutting_edge_features">ميزات متطورة</string>
|
||||||
|
<string name="early_access_updates">الوصول المبكر إلى التحديثات</string>
|
||||||
|
<string name="no_manual_installation">لا يوجد التثبيت اليدوي</string>
|
||||||
|
<string name="prioritized_support">الدعم ذو الأولوية</string>
|
||||||
|
<string name="helping_game_preservation">المساعدة في الحفاظ على اللعبة</string>
|
||||||
|
<string name="our_eternal_gratitude">امتناننا الأبدي</string>
|
||||||
|
<string name="are_you_interested">هل انت مهتم؟</string>
|
||||||
|
|
||||||
|
<!-- General settings strings -->
|
||||||
|
<string name="frame_limit_enable">الحد من السرعة</string>
|
||||||
|
<string name="frame_limit_enable_description">يحد من سرعة المحاكاة بنسبة محددة من السرعة العادية</string>
|
||||||
|
<string name="frame_limit_slider">الحد من السرعة في المئة</string>
|
||||||
|
<string name="frame_limit_slider_description">يحدد النسبة المئوية للحد من سرعة المحاكاة. 100% هي السرعة الطبيعية. ستؤدي القيم الأعلى أو الأدنى إلى زيادة أو تقليل حد السرعة.</string>
|
||||||
|
<string name="cpu_accuracy">دقة وحدة المعالجة المركزية</string>
|
||||||
|
<string name="value_with_units">%1$s%2$s</string>
|
||||||
|
|
||||||
|
<!-- System settings strings -->
|
||||||
|
<string name="use_docked_mode">وضع الإرساء</string>
|
||||||
|
<string name="use_docked_mode_description">زيادة الدقة، وانخفاض الأداء. يتم استخدام الوضع المحمول عند تعطيله، مما يؤدي إلى خفض الدقة وزيادة الأداء.</string>
|
||||||
|
<string name="emulated_region">المنطقة التي تمت محاكاتها</string>
|
||||||
|
<string name="emulated_language">لغة المحاكاه</string>
|
||||||
|
<string name="select_rtc_date">حدد التاريخ و الساعة في الوقت الحقيقي</string>
|
||||||
|
<string name="select_rtc_time">حدد وقت الساعة في الوقت الفعلي</string>
|
||||||
|
<string name="use_custom_rtc">ساعة مخصصة في الوقت الحقيقي</string>
|
||||||
|
<string name="use_custom_rtc_description">يسمح لك بتعيين ساعة مخصصة في الوقت الفعلي منفصلة عن وقت النظام الحالي لديك</string>
|
||||||
|
<string name="set_custom_rtc">تعيين ساعة مخصصة في الوقت الحقيقي</string>
|
||||||
|
|
||||||
|
<!-- Graphics settings strings -->
|
||||||
|
<string name="renderer_accuracy">مستوى الدقة</string>
|
||||||
|
<string name="renderer_resolution">(Handheld/Docked) الدقة</string>
|
||||||
|
<string name="renderer_vsync">VSync وضع</string>
|
||||||
|
<string name="renderer_screen_layout">الاتجاه</string>
|
||||||
|
<string name="renderer_aspect_ratio">تناسب الابعاد</string>
|
||||||
|
<string name="renderer_anti_aliasing">طريقة مكافحة التعرج</string>
|
||||||
|
<string name="renderer_asynchronous_shaders">استخدم تظليل غير متزامن</string>
|
||||||
|
<string name="renderer_asynchronous_shaders_description">يجمع التظليل بشكل غير متزامن، مما يقلل من التأتأة ولكنه قد يؤدي إلى حدوث بعض الأخطاء.</string>
|
||||||
|
<string name="renderer_reactive_flushing">استخدم التنظيف التفاعلي</string>
|
||||||
|
<string name="renderer_reactive_flushing_description">تحسين دقة العرض في بعض الألعاب على حساب الأداء</string>
|
||||||
|
<string name="use_disk_shader_cache_description">يقلل من التأتأة عن طريق تخزين وتحميل التظليلات التي تم إنشاؤها محليًا.</string>
|
||||||
|
|
||||||
|
<!-- Debug settings strings -->
|
||||||
|
<string name="cpu">وحدة المعالج المركزية</string>
|
||||||
|
<string name="cpu_debug_mode">تصحيح أخطاء وحدة المعالجة المركزية</string>
|
||||||
|
<string name="cpu_debug_mode_description">يضع وحدة المعالجة المركزية في وضع التصحيح البطيء.</string>
|
||||||
|
<string name="gpu">GPU</string>
|
||||||
|
<string name="renderer_api">API</string>
|
||||||
|
<string name="renderer_debug">تصحيح الأخطاء الرسومية</string>
|
||||||
|
<string name="renderer_debug_description">يضبط واجهة برمجة تطبيقات الرسومات على وضع تصحيح الأخطاء البطيء.</string>
|
||||||
|
<string name="fastmem">Fastmem</string>
|
||||||
|
|
||||||
|
<!-- Audio settings strings -->
|
||||||
|
<string name="audio_output_engine">محرك الإخراج</string>
|
||||||
|
<string name="audio_volume">حجم</string>
|
||||||
|
<string name="audio_volume_description">يحدد حجم إخراج الصوت</string>
|
||||||
|
|
||||||
|
<!-- Miscellaneous -->
|
||||||
|
<string name="slider_default">افتراضي</string>
|
||||||
|
<string name="ini_saved">الإعدادات المحفوظة</string>
|
||||||
|
<string name="gameid_saved">الإعدادات المحفوظة لـ %1$s</string>
|
||||||
|
<string name="unimplemented_menu">القائمة غير المنفذة</string>
|
||||||
|
<string name="loading">جاري تحميل</string>
|
||||||
|
<string name="shutting_down">إيقاف تشغيل</string>
|
||||||
|
<string name="reset_setting_confirmation">هل تريد إعادة تعيين هذا الإعداد مرة أخرى إلى قيمته الافتراضية؟</string>
|
||||||
|
<string name="reset_to_default">إعادة تعيين إلى الافتراضي</string>
|
||||||
|
<string name="reset_all_settings">إعادة تعيين جميع الإعدادات؟</string>
|
||||||
|
<string name="reset_all_settings_description">سيتم إعادة تعيين كافة الإعدادات المتقدمة إلى تكوينها الافتراضي. هذا لا يمكن التراجع عنها.</string>
|
||||||
|
<string name="settings_reset">إعادة تعيين الأعدادات</string>
|
||||||
|
<string name="close">إغلاق</string>
|
||||||
|
<string name="learn_more">معرفة المزيد</string>
|
||||||
|
<string name="auto">تلقائي</string>
|
||||||
|
<string name="submit">إرسال</string>
|
||||||
|
<string name="string_null">قيمه خاليه</string>
|
||||||
|
<string name="string_import">استيراد</string>
|
||||||
|
<string name="export">تصدير</string>
|
||||||
|
<string name="export_failed">فشل التصدير</string>
|
||||||
|
<string name="import_failed">فشل الاستيراد</string>
|
||||||
|
<string name="cancelling">إلغاء</string>
|
||||||
|
|
||||||
|
<!-- GPU driver installation -->
|
||||||
|
<string name="select_gpu_driver">GPU حدد برنامج تشغيل</string>
|
||||||
|
<string name="select_gpu_driver_title">الحالي الخاص بك؟ GPU هل ترغب في استبدال برنامج تشغيل</string>
|
||||||
|
<string name="select_gpu_driver_install">تثبيت</string>
|
||||||
|
<string name="select_gpu_driver_default">افتراضي</string>
|
||||||
|
<string name="select_gpu_driver_use_default">يستخدم تعريف معالج الرسوميات الافتراضي</string>
|
||||||
|
<string name="select_gpu_driver_error">تم تحديد برنامج تشغيل غير صالح ، باستخدام النظام الافتراضي</string>
|
||||||
|
<string name="system_gpu_driver">تعريف معالج الرسوميات الخاص بالنظام</string>
|
||||||
|
<string name="installing_driver">جارٍ تثبيت برنامج التشغيل…</string>
|
||||||
|
|
||||||
|
<!-- Preferences Screen -->
|
||||||
|
<string name="preferences_settings">إعدادات</string>
|
||||||
|
<string name="preferences_general">عام</string>
|
||||||
|
<string name="preferences_system">النظام</string>
|
||||||
|
<string name="preferences_graphics">الرسوميات</string>
|
||||||
|
<string name="preferences_audio">الصوت</string>
|
||||||
|
<string name="preferences_theme">السمة واللون</string>
|
||||||
|
<string name="preferences_debug">تصحيح الأخطاء</string>
|
||||||
|
|
||||||
|
<!-- ROM loading errors -->
|
||||||
|
<string name="loader_error_encrypted">الخاص بك ROM تم تشفير</string>
|
||||||
|
<string name="loader_error_video_core">حدث خطأ أثناء تهيئة مركز الفيديو</string>
|
||||||
|
<string name="loader_error_invalid_format">ROM غير قادر على تحميل</string>
|
||||||
|
<string name="loader_error_file_not_found">غير موجود ROM ملف</string>
|
||||||
|
|
||||||
|
<!-- Emulation Menu -->
|
||||||
|
<string name="emulation_exit">الخروج من المحاكاة</string>
|
||||||
|
<string name="emulation_done">منجز</string>
|
||||||
|
<string name="emulation_fps_counter">عداد إطار/ثانية</string>
|
||||||
|
<string name="emulation_toggle_controls">تبديل عناصر التحكم</string>
|
||||||
|
<string name="emulation_rel_stick_center">مركز العصا النسبي</string>
|
||||||
|
<string name="emulation_dpad_slide">مزلاق أزرار الاتجاهات</string>
|
||||||
|
<string name="emulation_haptics">الاهتزازات الديناميكية</string>
|
||||||
|
<string name="emulation_show_overlay">عرض التراكب</string>
|
||||||
|
<string name="emulation_toggle_all">تبديل الكل</string>
|
||||||
|
<string name="emulation_control_adjust">ضبط التراكب</string>
|
||||||
|
<string name="emulation_control_scale">حجم</string>
|
||||||
|
<string name="emulation_control_opacity">العتامه</string>
|
||||||
|
<string name="emulation_touch_overlay_reset">إعادة تعيين التراكب</string>
|
||||||
|
<string name="emulation_touch_overlay_edit">تحرير التراكب</string>
|
||||||
|
<string name="emulation_pause">إيقاف المحاكاة مؤقتًا</string>
|
||||||
|
<string name="emulation_unpause">إلغاء الإيقاف المؤقت للمضاهاة</string>
|
||||||
|
<string name="emulation_input_overlay">خيارات التراكب</string>
|
||||||
|
|
||||||
|
<string name="load_settings">جارٍ تحميل الإعدادات</string>
|
||||||
|
|
||||||
|
<!-- Software keyboard -->
|
||||||
|
<string name="software_keyboard">لوحة المفاتيح البرمجية</string>
|
||||||
|
|
||||||
|
<!-- Errors and warnings -->
|
||||||
|
<string name="abort_button">إلغاء</string>
|
||||||
|
<string name="continue_button">استمر</string>
|
||||||
|
<string name="system_archive_not_found">لم يتم العثور على أرشيف النظام</string>
|
||||||
|
<string name="system_archive_general">أرشيف النظام</string>
|
||||||
|
<string name="save_load_error">خطأ في الحفظ/التحميل</string>
|
||||||
|
<string name="fatal_error">خطا فادح</string>
|
||||||
|
<string name="performance_warning">سيؤدي إيقاف تشغيل هذا الإعداد إلى تقليل أداء المحاكاة بشكل ملحوظ! للحصول على أفضل تجربة، يوصى بترك هذا الإعداد ممكنًا.</string>
|
||||||
|
<string name="memory_formatted">%1$s %2$s</string>
|
||||||
|
<string name="no_game_present">لا توجد لعبة قابلة للتمهيد</string>
|
||||||
|
|
||||||
|
<!-- Region Names -->
|
||||||
|
<string name="region_japan">اليابان</string>
|
||||||
|
<string name="region_usa">الولايات المتحدة الأمريكية</string>
|
||||||
|
<string name="region_europe">أوروبا</string>
|
||||||
|
<string name="region_australia">أستراليا</string>
|
||||||
|
<string name="region_china">الصين</string>
|
||||||
|
<string name="region_korea">كوريا</string>
|
||||||
|
<string name="region_taiwan">تايوان</string>
|
||||||
|
|
||||||
|
<!-- Memory Sizes -->
|
||||||
|
<string name="memory_byte">Byte</string>
|
||||||
|
<string name="memory_kilobyte">KB</string>
|
||||||
|
<string name="memory_megabyte">MB</string>
|
||||||
|
<string name="memory_gigabyte">GB</string>
|
||||||
|
<string name="memory_terabyte">TB</string>
|
||||||
|
<string name="memory_petabyte">PB</string>
|
||||||
|
<string name="memory_exabyte">EB</string>
|
||||||
|
|
||||||
|
<!-- Renderer APIs -->
|
||||||
|
<string name="renderer_vulkan">Vulkan</string>
|
||||||
|
<string name="renderer_none">لاشيء</string>
|
||||||
|
|
||||||
|
<!-- Renderer Accuracy -->
|
||||||
|
<string name="renderer_accuracy_normal">عادي</string>
|
||||||
|
<string name="renderer_accuracy_high">عالي</string>
|
||||||
|
<string name="renderer_accuracy_extreme">Extreme (بطيء)</string>
|
||||||
|
|
||||||
|
<!-- Resolutions -->
|
||||||
|
<string name="resolution_half">0.5X (360p/540p)</string>
|
||||||
|
<string name="resolution_three_quarter">0.75X (540p/810p)</string>
|
||||||
|
<string name="resolution_one">1X (720p/1080p)</string>
|
||||||
|
<string name="resolution_two">2X (1440p/2160p) (بطيء)</string>
|
||||||
|
<string name="resolution_three">3X (2160p/3240p) (بطيء)</string>
|
||||||
|
<string name="resolution_four">4X (2880p/4320p) (بطيء)</string>
|
||||||
|
|
||||||
|
<!-- Renderer VSync -->
|
||||||
|
<string name="renderer_vsync_immediate">Immediate (Off)</string>
|
||||||
|
<string name="renderer_vsync_mailbox">Mailbox</string>
|
||||||
|
<string name="renderer_vsync_fifo">FIFO (On)</string>
|
||||||
|
<string name="renderer_vsync_fifo_relaxed">FIFO Relaxed</string>
|
||||||
|
|
||||||
|
<!-- Scaling Filters -->
|
||||||
|
<string name="scaling_filter_nearest_neighbor">Nearest Neighbor</string>
|
||||||
|
<string name="scaling_filter_bilinear">Bilinear</string>
|
||||||
|
<string name="scaling_filter_bicubic">Bicubic</string>
|
||||||
|
<string name="scaling_filter_gaussian">Gaussian</string>
|
||||||
|
<string name="scaling_filter_scale_force">ScaleForce</string>
|
||||||
|
<string name="scaling_filter_fsr">AMD FidelityFX™ Super Resolution</string>
|
||||||
|
|
||||||
|
<!-- Anti-Aliasing -->
|
||||||
|
<string name="anti_aliasing_none">لا شيء</string>
|
||||||
|
<string name="anti_aliasing_fxaa">FXAA</string>
|
||||||
|
<string name="anti_aliasing_smaa">SMAA</string>
|
||||||
|
|
||||||
|
<!-- Screen Layouts -->
|
||||||
|
<string name="screen_layout_landscape">افقي</string>
|
||||||
|
<string name="screen_layout_portrait">عمودي</string>
|
||||||
|
<string name="screen_layout_auto">تلقائي</string>
|
||||||
|
|
||||||
|
<!-- Aspect Ratios -->
|
||||||
|
<string name="ratio_default">(16:9) افتراضي</string>
|
||||||
|
<string name="ratio_force_four_three">4:3 فرض</string>
|
||||||
|
<string name="ratio_force_twenty_one_nine">21:9 فرض</string>
|
||||||
|
<string name="ratio_force_sixteen_ten">16:10 فرض</string>
|
||||||
|
<string name="ratio_stretch">تمتد إلى النافذة</string>
|
||||||
|
|
||||||
|
<!-- CPU Accuracy -->
|
||||||
|
<string name="cpu_accuracy_accurate">دقه</string>
|
||||||
|
<string name="cpu_accuracy_unsafe">غير آمن</string>
|
||||||
|
<string name="cpu_accuracy_paranoid">Paranoid (Slow)</string>
|
||||||
|
|
||||||
|
<!-- Gamepad Buttons -->
|
||||||
|
<string name="gamepad_d_pad">أزرار الاتجاهات</string>
|
||||||
|
<string name="gamepad_left_stick">العصا اليسرى</string>
|
||||||
|
<string name="gamepad_right_stick">العصا اليمنى</string>
|
||||||
|
<string name="gamepad_home">شاشة الإستقبال</string>
|
||||||
|
<string name="gamepad_screenshot">لقطة شاشة</string>
|
||||||
|
|
||||||
|
<!-- Disk shader cache -->
|
||||||
|
<string name="preparing_shaders">تحضير التظليل</string>
|
||||||
|
<string name="building_shaders">بناء التظليل</string>
|
||||||
|
|
||||||
|
<!-- Theme options -->
|
||||||
|
<string name="change_app_theme">تغيير سمة التطبيق</string>
|
||||||
|
<string name="theme_default">افتراضي</string>
|
||||||
|
<string name="theme_material_you">Material You</string>
|
||||||
|
|
||||||
|
<!-- Theme Modes -->
|
||||||
|
<string name="change_theme_mode">تغيير وضع السمة</string>
|
||||||
|
<string name="theme_mode_follow_system">اتبع النظام</string>
|
||||||
|
<string name="theme_mode_light">فاتح</string>
|
||||||
|
<string name="theme_mode_dark">غامق</string>
|
||||||
|
|
||||||
|
<!-- Audio output engines -->
|
||||||
|
<string name="cubeb">cubeb</string>
|
||||||
|
|
||||||
|
<!-- Black backgrounds theme -->
|
||||||
|
<string name="use_black_backgrounds">خلفيات سوداء</string>
|
||||||
|
<string name="use_black_backgrounds_description">عند استخدام المظهر الداكن، قم بتطبيق خلفيات سوداء.</string>
|
||||||
|
|
||||||
|
<!-- Picture-In-Picture -->
|
||||||
|
<string name="picture_in_picture">صورة داخل صورة</string>
|
||||||
|
<string name="picture_in_picture_description">تصغير النافذة عند وضعها في الخلفية</string>
|
||||||
|
<string name="pause">توقف</string>
|
||||||
|
<string name="play">تشغيل</string>
|
||||||
|
<string name="mute">كتم</string>
|
||||||
|
<string name="unmute">إلغاء الكتم</string>
|
||||||
|
|
||||||
|
<!-- Licenses screen strings -->
|
||||||
|
<string name="licenses">التراخيص</string>
|
||||||
|
<string name="license_fidelityfx_fsr_description">AMD ترقية عالية الجودة من</string>
|
||||||
|
</resources>
|
336
src/android/app/src/main/res/values-ckb/strings.xml
Normal file
336
src/android/app/src/main/res/values-ckb/strings.xml
Normal file
|
@ -0,0 +1,336 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||||
|
|
||||||
|
<string name="app_disclaimer">ئەم نەرمەکاڵایە یارییەکانی کۆنسۆلی نینتێندۆ سویچ کارپێدەکات. هیچ ناونیشانێکی یاری و کلیلی تێدا نییە..<br /><br />پێش ئەوەی دەست پێ بکەیت، تکایە شوێنی فایلی <![CDATA[<b> prod.keys </b>]]> دیاریبکە لە نێو کۆگای ئامێرەکەت.<br /><br /><![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">زیاتر فێربە</a>]]></string>
|
||||||
|
<string name="emulation_notification_channel_name">ئیمولەیشن کارایە</string>
|
||||||
|
<string name="emulation_notification_channel_description">ئاگادارکردنەوەیەکی بەردەوام نیشان دەدات کاتێک ئیمولەیشن کاردەکات.</string>
|
||||||
|
<string name="emulation_notification_running">یوزو کاردەکات</string>
|
||||||
|
<string name="notice_notification_channel_name">ئاگاداری و هەڵەکان</string>
|
||||||
|
<string name="notice_notification_channel_description">ئاگادارکردنەوەکان پیشان دەدات کاتێک شتێک بە هەڵەدا دەچێت.</string>
|
||||||
|
<string name="notification_permission_not_granted">مۆڵەتی ئاگادارکردنەوە نەدراوە!</string>
|
||||||
|
|
||||||
|
<!-- Setup strings -->
|
||||||
|
<string name="welcome">بەخێربێیت!</string>
|
||||||
|
<string name="welcome_description">فێربە چۆن <b>yuzu</b> ڕێکبخەیت و بچییە ناو ئیمولەیشن.</string>
|
||||||
|
<string name="get_started">دەست پێبکە</string>
|
||||||
|
<string name="keys">کلیلەکان</string>
|
||||||
|
<string name="keys_description">فایلی <b>prod.keys</b> هەڵبژێرە بە دوگمەی خوارەوە.</string>
|
||||||
|
<string name="select_keys">کلیلەکان هەڵبژێرە</string>
|
||||||
|
<string name="games">یاریەکان</string>
|
||||||
|
<string name="games_description">فۆڵدەری <b>Games</b> هەڵبژێرە بە دوگمەی خوارەوە.</string>
|
||||||
|
<string name="done">تەواو</string>
|
||||||
|
<string name="done_description">تۆ تەواو ئامادەیت.\nچێژ لە یارییەکانت وەربگرە!</string>
|
||||||
|
<string name="text_continue">بەردەوام بوون</string>
|
||||||
|
<string name="next">دواتر</string>
|
||||||
|
<string name="back">گەڕانەوە</string>
|
||||||
|
<string name="add_games">زیادکردنی یاری</string>
|
||||||
|
<string name="add_games_description">فۆڵدەری یارییەکانت هەڵبژێرە</string>
|
||||||
|
<!-- Home strings -->
|
||||||
|
<string name="home_games">یاریەکان</string>
|
||||||
|
<string name="home_search">گەڕان</string>
|
||||||
|
<string name="home_settings">ڕێکخستنەکان</string>
|
||||||
|
<string name="empty_gamelist">تا ئێستا هیچ فایلێک نەدۆزراوەتەوە یان هیچ ناونیشانێکی یاری هەڵنەبژێردراوە.</string>
|
||||||
|
<string name="search_and_filter_games">گەڕان و فلتەرکردنی یارییەکان</string>
|
||||||
|
<string name="select_games_folder">فۆڵدەری یارییەکان هەڵبژێرە</string>
|
||||||
|
<string name="select_games_folder_description">ڕێگە بە یوزو دەدات بۆ پڕکردنەوەی لیستی یارییەکان</string>
|
||||||
|
<string name="add_games_warning">هەڵبژاردنی فۆڵدەری یارییەکان تێپەڕدەکەیت؟</string>
|
||||||
|
<string name="add_games_warning_description">یارییەکان لە لیستی یارییەکاندا پیشان نادرێن ئەگەر فۆڵدەرێک هەڵنەبژێردرێت.</string>
|
||||||
|
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
|
||||||
|
<string name="home_search_games">گەڕان بەدوای یارییەکاندا</string>
|
||||||
|
<string name="games_dir_selected">ناونیشانی یارییەکان هەڵبژێردرا</string>
|
||||||
|
<string name="install_prod_keys">دابمەزرێنە prod.keys</string>
|
||||||
|
<string name="install_prod_keys_description">پێویستە بۆ کۆدکردنەوەى یارییە تاکەکەسییەکان</string>
|
||||||
|
<string name="install_prod_keys_warning">زیادکردنی کلیلەکان تێپەڕدەکەیت؟</string>
|
||||||
|
<string name="install_prod_keys_warning_description">کلیلی دروست پێویستە بۆ وەرگرتنی یارییەکانی تاکەکەسی. تەنها ئەپەکانی homebrew کاردەکەن ئەگەر بەردەوام بیت.</string>
|
||||||
|
<string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
|
||||||
|
<string name="notifications">ئاگادارکردنەوەکان</string>
|
||||||
|
<string name="notifications_description">بە دوگمەی خوارەوە مۆڵەتی ئاگادارکردنەوەکە بدە.</string>
|
||||||
|
<string name="give_permission">مۆڵەت بدە</string>
|
||||||
|
<string name="notification_warning">پێدانی مۆڵەتی ئاگادارکردنەوە تێپەڕدەکەیت؟</string>
|
||||||
|
<string name="notification_warning_description">یوزو ناتوانێت لە زانیاری گرنگ ئاگادارت بکاتەوە.</string>
|
||||||
|
<string name="permission_denied">مۆڵەت پێدان ڕەتکرایەوە</string>
|
||||||
|
<string name="permission_denied_description">زۆر جار ئەم مۆڵەتەت ڕەتکردۆتەوە و ئێستا دەبێت بە دەستی ڕێگەپێدان بکەیت لە ڕێکخستنەکانی سیستەمدا.</string>
|
||||||
|
<string name="about">دەربارە</string>
|
||||||
|
<string name="about_description">وەشانی دروستکردن، بیتبێن و زۆر شتیتر</string>
|
||||||
|
<string name="warning_help">یارمەتی</string>
|
||||||
|
<string name="warning_skip">پەڕاندن</string>
|
||||||
|
<string name="warning_cancel">ڕەتکردنەوە</string>
|
||||||
|
<string name="install_amiibo_keys">دامەزراندنی کلیلی Amiibo</string>
|
||||||
|
<string name="install_amiibo_keys_description">پێویستە بۆ بەکارهێنانی Amiibo لە یاریدا</string>
|
||||||
|
<string name="invalid_keys_file">فایلی کلیلێکی نادروست هەڵبژێردرا</string>
|
||||||
|
<string name="install_keys_success">کلیلەکان بە سەرکەوتوویی دامەزران</string>
|
||||||
|
<string name="reading_keys_failure">هەڵە لە خوێندنەوەی کۆدکردنی کلیل</string>
|
||||||
|
<string name="install_prod_keys_failure_extension_description">دڵنیابەوە کە فایلی کلیلەکانت درێژکراوەی .keys ی هەیە و دووبارە هەوڵبدەرەوە.</string>
|
||||||
|
<string name="install_amiibo_keys_failure_extension_description">دڵنیابە کە فایلی کلیلەکانت درێژکراوەی .bin ی هەیە و دووبارە هەوڵبدەرەوە.</string>
|
||||||
|
<string name="invalid_keys_error">کلیلی کۆدکردنی نادروستە</string>
|
||||||
|
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
|
||||||
|
<string name="install_keys_failure_description">فایلە هەڵبژێردراوەکە هەڵەیە یان تێکچووە. تکایە دووبارە کلیلەکانت دەربێنەوە.</string>
|
||||||
|
<string name="install_gpu_driver">دامەزراندنی وەگەڕخەری GPU</string>
|
||||||
|
<string name="install_gpu_driver_description">دامەزراندنی وەگەڕخەری بەدیل بۆ ئەوەی بە ئەگەرێکی زۆرەوە کارایی باشتر یان وردبینی هەبێت</string>
|
||||||
|
<string name="advanced_settings">ڕێکخستنە پێشکەوتووەکان</string>
|
||||||
|
<string name="settings_description">سازدانی ڕێکخستنەکانی ئیمولەیتەر</string>
|
||||||
|
<string name="search_recently_played">بەم دواییە یاری کردووە</string>
|
||||||
|
<string name="search_recently_added">بەم دواییە زیادکرا</string>
|
||||||
|
<string name="search_retail">بەتاک</string>
|
||||||
|
<string name="search_homebrew">هۆم بریو</string>
|
||||||
|
<string name="open_user_folder">کردنەوەی فۆڵدەری یوزو</string>
|
||||||
|
<string name="open_user_folder_description">بەڕێوەبردنی فایلە ناوخۆییەکانی یوزو</string>
|
||||||
|
<string name="theme_and_color_description">دەستکاری کردنی شێوازی ئەپەکە</string>
|
||||||
|
<string name="no_file_manager">هیچ فایل بەڕێوەبەرێک نەدۆزرایەوە</string>
|
||||||
|
<string name="notification_no_directory_link">نەتوانرا ناونیشانی یوزو بکرێتەوە</string>
|
||||||
|
<string name="notification_no_directory_link_description">تکایە شوێنی فۆڵدەری بەکارهێنەر لەگەڵ پانێڵی لایەنی فایل بەڕێوەبارەکان بە دەست بدۆزەرەوە.</string>
|
||||||
|
<string name="manage_save_data">بەڕێوەبردنی داتای پاشەکەوتکراو</string>
|
||||||
|
<string name="manage_save_data_description">داتای پاشەکەوتکراو دۆزراوە. تکایە لە خوارەوە بژاردەیەک هەڵبژێرە.</string>
|
||||||
|
<string name="import_export_saves_description">هاوردەکردن یان هەناردەکردنی فایلی پاشەکەوتکراو</string>
|
||||||
|
<string name="save_file_imported_success">بە سەرکەوتوویی هاوردە کرا</string>
|
||||||
|
<string name="save_file_invalid_zip_structure">پێکهاتەی شوێنی پاشەکەوتکراو نادروستە</string>
|
||||||
|
<string name="save_file_invalid_zip_structure_description">ناوی یەکەمی فۆڵدەر دەبێت ناسنامەی ناونیشانی یارییەکە بێت.</string>
|
||||||
|
<string name="import_saves">هاوردەکردن</string>
|
||||||
|
<string name="export_saves">هەناردەکردن</string>
|
||||||
|
<string name="install_firmware">دامەزراندنی پتەوواڵا</string>
|
||||||
|
<string name="install_firmware_description">پتەوواڵا دەبێت لە ئەرشیفی زیپدا بێت و پێویستە بۆ بووتکردنی هەندێک یاری</string>
|
||||||
|
<string name="firmware_installing">دامەزرانی پتەوواڵا</string>
|
||||||
|
<string name="firmware_installed_success">پتەوواڵا بە سەرکەوتوویی دامەزرا</string>
|
||||||
|
<string name="firmware_installed_failure">دامەزراندنی پتەوواڵا شکستی هێنا</string>
|
||||||
|
<string name="share_log">هاوبەشی پێکردنی لۆگەکانی چاککردنەوە</string>
|
||||||
|
<string name="share_log_description">فایلە لۆگەکەی یوزو هاوبەش بکە بۆ چاککردنی کێشەکان</string>
|
||||||
|
<string name="share_log_missing">هیچ فایلێکی لۆگ نەدۆزراوە</string>
|
||||||
|
<string name="install_game_content">دامەزراندنی ناوەڕۆکی یاری</string>
|
||||||
|
<string name="install_game_content_description">دامەزراندنی نوێکاری یارییەکان یان DLC</string>
|
||||||
|
<string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
|
||||||
|
<!-- About screen strings -->
|
||||||
|
<string name="gaia_is_not_real">گایا ڕاستەقینە نییە</string>
|
||||||
|
<string name="copied_to_clipboard">کۆپی کرا بۆ تەختەی نووسین</string>
|
||||||
|
<string name="about_app_description">ئیمۆلیتەرێکی سەرچاوە-کراوەی سویچ</string>
|
||||||
|
<string name="contributors">بەشداربووان</string>
|
||||||
|
<string name="contributors_description">دروستکراوە لەگەڵ \u2764 لەلایەن تیمەکەی یوزو</string>
|
||||||
|
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
|
||||||
|
<string name="licenses_description">ئەو پڕۆژانەی کە یوزوی بۆ ئەندرۆید ڕەخساند</string>
|
||||||
|
<string name="build">بونیات</string>
|
||||||
|
<string name="support_link">https://discord.gg/u77vRWY</string>
|
||||||
|
<string name="website_link">https://yuzu-emu.org/</string>
|
||||||
|
<string name="github_link">https://github.com/yuzu-emu</string>
|
||||||
|
|
||||||
|
<!-- Early access upgrade strings -->
|
||||||
|
<string name="early_access">بەزوویی دەسپێگەشتن</string>
|
||||||
|
<string name="get_early_access">بەدەستهێنانی بەزوویی دەسپێگەشتن</string>
|
||||||
|
<string name="play_store_link">https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea</string>
|
||||||
|
<string name="get_early_access_description">تایبەتمەندییە پێشکەوتووەکان، بەزوویی دەستگەیشتن بە نوێکارییەکان و زۆر شتی تر</string>
|
||||||
|
<string name="early_access_benefits">سوودەکانی بەزوویی دەسپێگەشتن</string>
|
||||||
|
<string name="cutting_edge_features">تایبەتمەندییە پێشکەوتووەکان</string>
|
||||||
|
<string name="early_access_updates">زوو دەستگەیشتن بە نوێکارییەکان</string>
|
||||||
|
<string name="no_manual_installation">چیتر دامەزراندنی دەستی نییە</string>
|
||||||
|
<string name="prioritized_support">پشتگیری لە پێشینە</string>
|
||||||
|
<string name="helping_game_preservation">یارمەتیدانی پاراستنی یارییەکان</string>
|
||||||
|
<string name="our_eternal_gratitude">سوپاس و پێزانینی هەمیشەییمان</string>
|
||||||
|
<string name="are_you_interested">ئایا تۆ خوازیاریت؟</string>
|
||||||
|
|
||||||
|
<!-- General settings strings -->
|
||||||
|
<string name="frame_limit_enable">سنووردارکردنی خێرایی</string>
|
||||||
|
<string name="frame_limit_enable_description">خێرایی ئیمولەیشن سنووردار دەکات بۆ ڕێژەیەکی دیاریکراو لە خێرایی ئاسایی.</string>
|
||||||
|
<string name="frame_limit_slider">سنووردارکردنی لەسەدای خێرایی</string>
|
||||||
|
<string name="frame_limit_slider_description">ڕێژەی سەدی دیاری دەکات بۆ سنووردارکردنی خێرایی ئیمولەیشن. 100% خێرایی ئاساییە. بەهایی بەرزتر یان نزمتر دەبێتە هۆی زیاد یان کەمکردنەوەی سنووری خێرایی.</string>
|
||||||
|
<string name="cpu_accuracy">وردی CPU</string>
|
||||||
|
<!-- System settings strings -->
|
||||||
|
<string name="use_docked_mode">دۆخی دۆککراو</string>
|
||||||
|
<string name="use_docked_mode_description">ڕوونی زیاد دەکات، کارایی کەم دەکاتەوە. دۆخی دەستی بەکاردێت کاتێک لەکاردەخرێت، ئەمەش ڕوونی دادەبەزێنێت و کارایی زیاد دەکات.</string>
|
||||||
|
<string name="emulated_region">ناوچەی ئیمولەیشن</string>
|
||||||
|
<string name="emulated_language">زمانی ئیمولەیتەر</string>
|
||||||
|
<string name="select_rtc_date">هەڵبژاردنی بەرواری RTC</string>
|
||||||
|
<string name="select_rtc_time">هەڵبژاردنی کاتی RTC</string>
|
||||||
|
<string name="use_custom_rtc">RTCی تایبەتمەند</string>
|
||||||
|
<string name="use_custom_rtc_description">ڕێگەت پێدەدات کاتژمێرێکی کاتی ڕاستەقینەی تایبەتمەند دابنێیت کە جیاوازە لە کاتی ئێستای سیستەمەکەت.</string>
|
||||||
|
<string name="set_custom_rtc">دانانی RTCی تایبەتمەند</string>
|
||||||
|
|
||||||
|
<!-- Graphics settings strings -->
|
||||||
|
<string name="renderer_accuracy">ئاستی وردبینی</string>
|
||||||
|
<string name="renderer_resolution">ڕوونی (دۆخی دەستی/دۆخی دۆک)</string>
|
||||||
|
<string name="renderer_vsync">دۆخی VSync</string>
|
||||||
|
<string name="renderer_aspect_ratio">ڕێژەی ڕووبەری شاشە</string>
|
||||||
|
<string name="renderer_scaling_filter">فلتەری گونجاندنی پەنجەرە</string>
|
||||||
|
<string name="renderer_anti_aliasing">شێوازی دژە-خاوڕۆیی</string>
|
||||||
|
<string name="renderer_force_max_clock">ناچاریکردن بۆ زۆرترین کاتژمێر (تەنها ئەدرینۆ)</string>
|
||||||
|
<string name="renderer_force_max_clock_description">GPU ناچار دەکات بە زۆرترین کاتژمێر کاربکات (هێشتا سنووردارکردنی گەرمی جێبەجێ دەکرێت).</string>
|
||||||
|
<string name="renderer_asynchronous_shaders">بەکارهێنانی سێبەری ناهاوسەنگ</string>
|
||||||
|
<string name="renderer_asynchronous_shaders_description">سێبەرەکان بە شێوەیەکی ناهاوسەنگ کۆدەکاتەوە، پچڕپچڕی کەمدەکاتەوە بەڵام لەوانەیە گلێچ دروستکا.</string>
|
||||||
|
<string name="renderer_reactive_flushing">بەکارهێنانی بەرپێچدەرەوە</string>
|
||||||
|
<string name="renderer_reactive_flushing_description">وردی ڕێندەرکردن لە هەندێک یاریدا باشتر دەکات لەسەر تێچووی کارایی.</string>
|
||||||
|
<string name="use_disk_shader_cache">بیرگەخێرای سێبەری دیسک</string>
|
||||||
|
<string name="use_disk_shader_cache_description">پچڕپچڕی کەمدەکاتەوە بە هەڵگرتن و بارکردنی سێبەری دروستکراو لە ناوخۆدا.</string>
|
||||||
|
|
||||||
|
<!-- Debug settings strings -->
|
||||||
|
<string name="cpu">CPU</string>
|
||||||
|
<string name="renderer_api">API گرافیک</string>
|
||||||
|
<string name="renderer_debug">چاککردنەوەی گرافیک</string>
|
||||||
|
<string name="renderer_debug_description">API ی گرافیکەکان ڕێکدەخات بۆ دۆخی چاککردنی خاو.</string>
|
||||||
|
<string name="audio_volume">قەبارەی دەنگی</string>
|
||||||
|
<string name="audio_volume_description">دیاریکردنی قەبارەی دەنگی دەرچووی بیستۆک و بزوێنەری دەنگی دەرەکی.</string>
|
||||||
|
|
||||||
|
<!-- Miscellaneous -->
|
||||||
|
<string name="slider_default">بنەڕەت</string>
|
||||||
|
<string name="ini_saved">ڕێکخستنە پاشەکەوتکراوەکان</string>
|
||||||
|
<string name="gameid_saved">ڕێکخستنە پاشەکەوتکراوەکان بۆ %1$s</string>
|
||||||
|
<string name="error_saving">هەڵە لە پاشەکەوتکردن %1$s.ini: %2$s</string>
|
||||||
|
<string name="loading">بارکردن...</string>
|
||||||
|
<string name="reset_setting_confirmation">ئایا دەتەوێت ئەم ڕێکخستنە بگەڕێنیتەوە بۆ بەهای بنەڕەتی خۆی؟</string>
|
||||||
|
<string name="reset_to_default">دوبارە ڕێکخستنەوەی بۆ بنەڕەت</string>
|
||||||
|
<string name="reset_all_settings">هەموو ڕێکخستنەکان دوبارە ڕێک دەخاتەوە؟</string>
|
||||||
|
<string name="reset_all_settings_description">هەموو ڕێکخستنە پێشکەوتووەکان دەگەڕێنەوە بۆ ڕێکخستنی بنەڕەتی خۆیان. پاشگەز بوونەوەی نییه.</string>
|
||||||
|
<string name="settings_reset">دوبارە ڕێککردنەوەی ڕێکخستنەکان</string>
|
||||||
|
<string name="close">داخستن</string>
|
||||||
|
<string name="learn_more">زیاتر فێربە</string>
|
||||||
|
<string name="auto">خودکار</string>
|
||||||
|
<string name="submit">پێشکەشکردن</string>
|
||||||
|
<string name="string_import">هاوردەکردن</string>
|
||||||
|
<string name="export">هەناردەکردن</string>
|
||||||
|
<!-- GPU driver installation -->
|
||||||
|
<string name="select_gpu_driver">هەڵبژاردنی وەگەڕخەری GPU</string>
|
||||||
|
<string name="select_gpu_driver_title">حەز دەکەیت وەگەڕخەری GPU ی ئێستات بگۆڕیت؟</string>
|
||||||
|
<string name="select_gpu_driver_install">دامەزراندن</string>
|
||||||
|
<string name="select_gpu_driver_default">بنەڕەت</string>
|
||||||
|
<string name="select_gpu_driver_use_default">بەکارهێنانی وەگەڕخەری GPU ی بنەڕەت</string>
|
||||||
|
<string name="select_gpu_driver_error">وەگەڕخەری نادروست هەڵبژێردرا، بە بەکارهێنانی بنەڕەتی سیستەم!</string>
|
||||||
|
<string name="system_gpu_driver">وەگەڕخەری GPU ی سیستەم</string>
|
||||||
|
<string name="installing_driver">دامەزراندنی وەگەڕخەر...</string>
|
||||||
|
|
||||||
|
<!-- Preferences Screen -->
|
||||||
|
<string name="preferences_settings">ڕێکخستنەکان</string>
|
||||||
|
<string name="preferences_general">گشتی</string>
|
||||||
|
<string name="preferences_system">سیستەم</string>
|
||||||
|
<string name="preferences_graphics">گرافیک</string>
|
||||||
|
<string name="preferences_audio">دەنگ</string>
|
||||||
|
<string name="preferences_theme">ڕەنگ و ڕووکار</string>
|
||||||
|
<string name="preferences_debug">چاککردنەوە</string>
|
||||||
|
|
||||||
|
<!-- ROM loading errors -->
|
||||||
|
<string name="loader_error_encrypted">ڕۆمەکەت کۆدکراوە</string>
|
||||||
|
<string name="loader_error_encrypted_keys_description"><![CDATA[تکایە دڵنیابەوە لەدامەزراوی <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> فایلەکەت بۆ ئەوەی بتوانرێت یارییەکان کۆد بکرێنەوە.]]></string>
|
||||||
|
<string name="loader_error_video_core">هەڵەیەک لە دەستپێکردنی ناوەکی ڤیدیۆکەدا ڕوویدا</string>
|
||||||
|
<string name="loader_error_video_core_description">ئەمەش بەزۆری بەهۆی وەگەڕخەرێکی ناتەبای GPU ەوەیە. دامەزراندنی وەگەڕخەری GPU ی تایبەتمەندکراو لەوانەیە ئەم کێشەیە چارەسەر بکات.</string>
|
||||||
|
<string name="loader_error_invalid_format">ناتوانرێت ڕۆم باربکرێت</string>
|
||||||
|
<string name="loader_error_file_not_found">فایلی ڕۆم بوونی نییە</string>
|
||||||
|
|
||||||
|
<!-- Emulation Menu -->
|
||||||
|
<string name="emulation_exit">دەرچوون لە ئیمولەیشن</string>
|
||||||
|
<string name="emulation_done">تەواو</string>
|
||||||
|
<string name="emulation_fps_counter">FPS ژمێر</string>
|
||||||
|
<string name="emulation_toggle_controls">گۆڕینی کۆنتڕۆڵ</string>
|
||||||
|
<string name="emulation_rel_stick_center">ناوەندی گێڕ بەنزیکەیی</string>
|
||||||
|
<string name="emulation_dpad_slide">خلیسکانی 4 دوگمەکە</string>
|
||||||
|
<string name="emulation_haptics">لەرینەوەی پەنجەلێدان</string>
|
||||||
|
<string name="emulation_show_overlay">نیشاندانی داپۆشەر</string>
|
||||||
|
<string name="emulation_toggle_all">گۆڕینی سەرجەم</string>
|
||||||
|
<string name="emulation_control_adjust">ڕێکخستنی داپۆشەر</string>
|
||||||
|
<string name="emulation_control_scale">پێوەر</string>
|
||||||
|
<string name="emulation_control_opacity">ڕوونی</string>
|
||||||
|
<string name="emulation_touch_overlay_reset">دووبارە ڕێکخستنەوەی داپۆشەر</string>
|
||||||
|
<string name="emulation_touch_overlay_edit">دەستکاریکردنی داپۆشەر</string>
|
||||||
|
<string name="emulation_pause">وەستاندنی ئیمولەیشن</string>
|
||||||
|
<string name="emulation_unpause">لادانی وەستاندنی ئیمولەیشن</string>
|
||||||
|
<string name="emulation_input_overlay">هەڵبژاردەکانی داپۆشەر</string>
|
||||||
|
|
||||||
|
<string name="load_settings">بارکردنی ڕێکخستنەکان...</string>
|
||||||
|
|
||||||
|
<!-- Software keyboard -->
|
||||||
|
<string name="software_keyboard">کیبۆردی نەرمەکاڵا</string>
|
||||||
|
|
||||||
|
<!-- Errors and warnings -->
|
||||||
|
<string name="abort_button">دەربارە</string>
|
||||||
|
<string name="continue_button">بەردەوام بوون</string>
|
||||||
|
<string name="system_archive_not_found">ئەرشیفی سیستەم نەدۆزراوە</string>
|
||||||
|
<string name="system_archive_not_found_message">%s دیار نییە. تکایە ئەرشیفی سیستەمەکەت فڕێ بدە.\nبەردەوامی ئیمولەیشن لەوانەیە ببێتە هۆی تێکچوون و فڕێدانەدەرەوە.</string>
|
||||||
|
<string name="system_archive_general">ئەرشیفێکی سیستەم</string>
|
||||||
|
<string name="save_load_error">هەڵەی پاشەکەوتکردن/بارکردن</string>
|
||||||
|
<string name="fatal_error">هەڵەی کوشندە</string>
|
||||||
|
<string name="fatal_error_message">هەڵەیەکی کوشندە ڕوویدا. بۆ وردەکارییەکان لۆگەکە بپشکنە.\nبەردەوامی ئیمولەیشن لەوانەیە ببێتە هۆی تێکچوون و فڕێدانەدەرەوە.</string>
|
||||||
|
<string name="performance_warning">کوژاندنەوەی ئەم ڕێکخستنە دەبێتە هۆی کەمکردنەوەی کارایی ئیمولەیشن! بۆ باشترین ئەزموون، باشترە ئەم ڕێکخستنە چالاک بهێڵیتەوە.</string>
|
||||||
|
<!-- Region Names -->
|
||||||
|
<string name="region_japan">ژاپۆن</string>
|
||||||
|
<string name="region_usa">ئەمریکا</string>
|
||||||
|
<string name="region_europe">ئەورووپا</string>
|
||||||
|
<string name="region_australia">ئوسترالیا</string>
|
||||||
|
<string name="region_china">چین</string>
|
||||||
|
<string name="region_korea">کۆریا</string>
|
||||||
|
<string name="region_taiwan">تایوان</string>
|
||||||
|
|
||||||
|
<string name="memory_gigabyte">GB</string>
|
||||||
|
<!-- Renderer APIs -->
|
||||||
|
<string name="renderer_vulkan">ڤوڵکان</string>
|
||||||
|
<string name="renderer_none">هیچ</string>
|
||||||
|
|
||||||
|
<!-- Renderer Accuracy -->
|
||||||
|
<string name="renderer_accuracy_normal">ئاسایی</string>
|
||||||
|
<string name="renderer_accuracy_high">بەرز</string>
|
||||||
|
<string name="renderer_accuracy_extreme">ئەوپەڕ (خاو)</string>
|
||||||
|
|
||||||
|
<!-- Resolutions -->
|
||||||
|
<string name="resolution_half">0.5X (360p/540p)</string>
|
||||||
|
<string name="resolution_three_quarter">0.75X (540p/810p)</string>
|
||||||
|
<string name="resolution_one">1X (720p/1080p)</string>
|
||||||
|
<string name="resolution_two">2X (1440p/2160p) (خاو)</string>
|
||||||
|
<string name="resolution_three">3X (2160p/3240p) (خاو)</string>
|
||||||
|
<string name="resolution_four">4X (2880p/4320p) (خاو)</string>
|
||||||
|
|
||||||
|
<!-- Renderer VSync -->
|
||||||
|
<string name="renderer_vsync_immediate">دەستبەجێ (کوژاوە)</string>
|
||||||
|
<string name="renderer_vsync_mailbox">سندوقی پۆستە</string>
|
||||||
|
<string name="renderer_vsync_fifo">FIFO (پێکراو)</string>
|
||||||
|
<string name="renderer_vsync_fifo_relaxed">FIFO ئارام</string>
|
||||||
|
|
||||||
|
<!-- Scaling Filters -->
|
||||||
|
<string name="scaling_filter_nearest_neighbor">نزیکترین دراوسێ</string>
|
||||||
|
<string name="scaling_filter_bilinear">دوو هێڵی</string>
|
||||||
|
<string name="scaling_filter_bicubic">دووخشتەکی</string>
|
||||||
|
<string name="scaling_filter_gaussian">گاوسی</string>
|
||||||
|
<string name="scaling_filter_scale_force">پێوەرهێز</string>
|
||||||
|
<string name="scaling_filter_fsr">AMD FidelityFX™ سوپەر ووردبینی</string>
|
||||||
|
|
||||||
|
<!-- Anti-Aliasing -->
|
||||||
|
<string name="anti_aliasing_none">هیچ</string>
|
||||||
|
<string name="anti_aliasing_fxaa">FXAA</string>
|
||||||
|
<string name="anti_aliasing_smaa">SMAA</string>
|
||||||
|
|
||||||
|
<string name="screen_layout_auto">خودکار</string>
|
||||||
|
|
||||||
|
<!-- Aspect Ratios -->
|
||||||
|
<string name="ratio_default">بنەڕەت (16:9)</string>
|
||||||
|
<string name="ratio_force_four_three">ڕووبەری 4:3</string>
|
||||||
|
<string name="ratio_force_twenty_one_nine">ڕووبەری 21:9</string>
|
||||||
|
<string name="ratio_force_sixteen_ten">ڕووبەری 16:10</string>
|
||||||
|
<string name="ratio_stretch">کشانی پڕ بەشاشە</string>
|
||||||
|
|
||||||
|
<!-- CPU Accuracy -->
|
||||||
|
<string name="cpu_accuracy_accurate">وورد</string>
|
||||||
|
<string name="cpu_accuracy_unsafe">ناسەقامگیر</string>
|
||||||
|
<string name="cpu_accuracy_paranoid">بەگومان (خاو)</string>
|
||||||
|
|
||||||
|
<!-- Gamepad Buttons -->
|
||||||
|
<string name="gamepad_d_pad">4 دوگمەکە</string>
|
||||||
|
<string name="gamepad_left_stick">گێڕی چەپ</string>
|
||||||
|
<string name="gamepad_right_stick">گێڕی ڕاست</string>
|
||||||
|
<string name="gamepad_home">ماڵەوە</string>
|
||||||
|
<string name="gamepad_screenshot">وێنەگرتنی شاشە</string>
|
||||||
|
|
||||||
|
<!-- Disk shader cache -->
|
||||||
|
<string name="preparing_shaders">ئامادەکردنی سێبەرەکان</string>
|
||||||
|
<string name="building_shaders">دروستکردنی سێبەرەکان</string>
|
||||||
|
|
||||||
|
<!-- Theme options -->
|
||||||
|
<string name="change_app_theme">گۆڕینی ڕووکاری ئەپەکە</string>
|
||||||
|
<string name="theme_default">بنەڕەت</string>
|
||||||
|
<string name="theme_material_you">کەرەستەی تۆ</string>
|
||||||
|
|
||||||
|
<!-- Theme Modes -->
|
||||||
|
<string name="change_theme_mode">گۆڕینی دۆخی ڕووکار</string>
|
||||||
|
<string name="theme_mode_follow_system">پەیڕەوی کردنی سیستەم</string>
|
||||||
|
<string name="theme_mode_light">ڕوناکی</string>
|
||||||
|
<string name="theme_mode_dark">تاریک</string>
|
||||||
|
|
||||||
|
<!-- Black backgrounds theme -->
|
||||||
|
<string name="use_black_backgrounds">پاشبنەمای ڕەش</string>
|
||||||
|
<string name="use_black_backgrounds_description">لە کاتی بەکارهێنانی ڕووکاری تاریکدا، پاشبنەمای ڕەش دادەنێ.</string>
|
||||||
|
|
||||||
|
<!-- Licenses screen strings -->
|
||||||
|
<string name="licenses">مۆڵەتەکان</string>
|
||||||
|
<string name="license_fidelityfx_fsr_description">بەرزکردنەوەی کوالێتی بەرز لە کۆمپانیای AMD</string>
|
||||||
|
</resources>
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||||
|
|
||||||
<string name="app_disclaimer">Diese Software kann Spiele für die Nintendo Switch abspielen. Keine Spiele oder Spielekeys sind enthalten.<br /><br />Bevor du beginnst, bitte halte deine <![CDATA[<b> prod.keys </b>]]> auf deinem Gerät bereit. .<br /><br /><![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Mehr Infos</a>]]></string>
|
<string name="app_disclaimer">Diese Software kann Spiele für die Nintendo Switch abspielen. Keine Spiele oder Spielekeys sind enthalten.<br /><br />Bevor du beginnst, bitte halte deine <![CDATA[<b> prod.keys </b>]]> auf deinem Gerät bereit. .<br /><br /><![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Mehr Infos</a>]]></string>
|
||||||
<string name="emulation_notification_channel_name">Emulation ist aktiv</string>
|
<string name="emulation_notification_channel_name">Emulation ist aktiv</string>
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
<string name="back">Zurück</string>
|
<string name="back">Zurück</string>
|
||||||
<string name="add_games">Spiele hinzufügen</string>
|
<string name="add_games">Spiele hinzufügen</string>
|
||||||
<string name="add_games_description">Spieleverzeichnis auswählen</string>
|
<string name="add_games_description">Spieleverzeichnis auswählen</string>
|
||||||
|
<string name="step_complete">Fertig!</string>
|
||||||
|
|
||||||
<!-- Home strings -->
|
<!-- Home strings -->
|
||||||
<string name="home_games">Spiele</string>
|
<string name="home_games">Spiele</string>
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
<string name="add_games_warning_description">Spiele werden in der Spieleliste nicht angezeigt, wenn kein Ordner ausgewählt ist.</string>
|
<string name="add_games_warning_description">Spiele werden in der Spieleliste nicht angezeigt, wenn kein Ordner ausgewählt ist.</string>
|
||||||
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
|
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
|
||||||
<string name="home_search_games">Spiele suchen</string>
|
<string name="home_search_games">Spiele suchen</string>
|
||||||
|
<string name="search_settings">Einstellungen suchen</string>
|
||||||
<string name="games_dir_selected">Spieleverzeichnis ausgewählt</string>
|
<string name="games_dir_selected">Spieleverzeichnis ausgewählt</string>
|
||||||
<string name="install_prod_keys">prod.keys installieren</string>
|
<string name="install_prod_keys">prod.keys installieren</string>
|
||||||
<string name="install_prod_keys_description">Zum Entschlüsseln von Spielen benötigt</string>
|
<string name="install_prod_keys_description">Zum Entschlüsseln von Spielen benötigt</string>
|
||||||
|
@ -60,8 +62,11 @@
|
||||||
<string name="invalid_keys_file">Ungültige Schlüsseldatei ausgewählt</string>
|
<string name="invalid_keys_file">Ungültige Schlüsseldatei ausgewählt</string>
|
||||||
<string name="install_keys_success">Schlüssel erfolgreich installiert</string>
|
<string name="install_keys_success">Schlüssel erfolgreich installiert</string>
|
||||||
<string name="reading_keys_failure">Fehler beim Lesen der Schlüssel</string>
|
<string name="reading_keys_failure">Fehler beim Lesen der Schlüssel</string>
|
||||||
|
<string name="install_prod_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".keys\" hat, und versuchen Sie es erneut.</string>
|
||||||
|
<string name="install_amiibo_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".bin\" hat, und versuchen Sie es erneut.</string>
|
||||||
<string name="invalid_keys_error">Ungültige Schlüssel</string>
|
<string name="invalid_keys_error">Ungültige Schlüssel</string>
|
||||||
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
|
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
|
||||||
|
<string name="install_keys_failure_description">Die ausgewählte Datei ist falsch oder beschädigt. Bitte kopieren Sie Ihre Schlüssel erneut.</string>
|
||||||
<string name="install_gpu_driver">GPU-Treiber installieren</string>
|
<string name="install_gpu_driver">GPU-Treiber installieren</string>
|
||||||
<string name="install_gpu_driver_description">Alternative Treiber für eventuell bessere Leistung oder Genauigkeit installieren</string>
|
<string name="install_gpu_driver_description">Alternative Treiber für eventuell bessere Leistung oder Genauigkeit installieren</string>
|
||||||
<string name="advanced_settings">Erweiterte Einstellungen</string>
|
<string name="advanced_settings">Erweiterte Einstellungen</string>
|
||||||
|
@ -84,7 +89,17 @@
|
||||||
<string name="save_file_invalid_zip_structure_description">Der erste Unterordnername muss die Titel-ID des Spiels sein.</string>
|
<string name="save_file_invalid_zip_structure_description">Der erste Unterordnername muss die Titel-ID des Spiels sein.</string>
|
||||||
<string name="import_saves">Importieren</string>
|
<string name="import_saves">Importieren</string>
|
||||||
<string name="export_saves">Exportieren</string>
|
<string name="export_saves">Exportieren</string>
|
||||||
|
<string name="install_firmware">Firmware installieren</string>
|
||||||
|
<string name="install_firmware_description">Die Firmware muss in einem ZIP-Archiv vorliegen und wird zum Booten einiger Spiele benötigt</string>
|
||||||
|
<string name="firmware_installing">Firmware wird installiert</string>
|
||||||
|
<string name="firmware_installed_success">Die Firmware wurde erfolgreich installiert!</string>
|
||||||
|
<string name="firmware_installed_failure">Bei der Firmware installation ist etwas fehlgeschlagen.</string>
|
||||||
|
<string name="share_log">Debug-Logs teilen</string>
|
||||||
|
<string name="share_log_description">Debug-Logs an yuzu zur Untersuchung absenden</string>
|
||||||
|
<string name="share_log_missing">Keine Log-Datei gefunden</string>
|
||||||
|
<string name="install_game_content">Spiel installieren</string>
|
||||||
|
<string name="install_game_content_description">Spiel Update oder DLC installieren</string>
|
||||||
|
<string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
|
||||||
<!-- About screen strings -->
|
<!-- About screen strings -->
|
||||||
<string name="gaia_is_not_real">Gaia ist nicht real</string>
|
<string name="gaia_is_not_real">Gaia ist nicht real</string>
|
||||||
<string name="copied_to_clipboard">In die Zwischenablage kopiert</string>
|
<string name="copied_to_clipboard">In die Zwischenablage kopiert</string>
|
||||||
|
@ -92,7 +107,10 @@
|
||||||
<string name="contributors">Beitragende</string>
|
<string name="contributors">Beitragende</string>
|
||||||
<string name="contributors_description">Gemacht mit \u2764 vom yuzu Team</string>
|
<string name="contributors_description">Gemacht mit \u2764 vom yuzu Team</string>
|
||||||
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
|
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
|
||||||
|
<string name="licenses_description">Projekte, die yuzu für Android möglich machen </string>
|
||||||
<string name="build">Build</string>
|
<string name="build">Build</string>
|
||||||
|
<string name="user_data">Nutzerdaten</string>
|
||||||
|
<string name="user_data_export_cancelled">Export abgebrochen</string>
|
||||||
<string name="support_link">https://discord.gg/u77vRWY</string>
|
<string name="support_link">https://discord.gg/u77vRWY</string>
|
||||||
<string name="website_link">https://yuzu-emu.org/</string>
|
<string name="website_link">https://yuzu-emu.org/</string>
|
||||||
<string name="github_link">https://github.com/yuzu-emu</string>
|
<string name="github_link">https://github.com/yuzu-emu</string>
|
||||||
|
@ -107,45 +125,39 @@
|
||||||
<string name="early_access_updates">Früherer Zugriff auf Updates</string>
|
<string name="early_access_updates">Früherer Zugriff auf Updates</string>
|
||||||
<string name="no_manual_installation">Keine manuelle Installation</string>
|
<string name="no_manual_installation">Keine manuelle Installation</string>
|
||||||
<string name="prioritized_support">Priorisierte Unterstützung</string>
|
<string name="prioritized_support">Priorisierte Unterstützung</string>
|
||||||
|
<string name="helping_game_preservation">Beitrag zur Erhaltung der Spiele</string>
|
||||||
<string name="our_eternal_gratitude">Unsere ewige Dankbarkeit</string>
|
<string name="our_eternal_gratitude">Unsere ewige Dankbarkeit</string>
|
||||||
<string name="are_you_interested">Bist du interessiert?</string>
|
<string name="are_you_interested">Bist du interessiert?</string>
|
||||||
|
|
||||||
<!-- General settings strings -->
|
<!-- General settings strings -->
|
||||||
<string name="frame_limit_enable">Geschwindigkeitsbegrenzung aktivieren</string>
|
<string name="frame_limit_enable">Limitierte Geschwindigkeit</string>
|
||||||
<string name="frame_limit_enable_description">Wenn aktiviert, wird die Emulationsgeschwindigkeit auf einen Prozentsatz der normalen Geschwindigkeit begrenzt.</string>
|
<string name="frame_limit_enable_description">Limitiert die Geschwindigkeit auf einen von dir festgelegten Prozentsatz.</string>
|
||||||
<string name="frame_limit_slider">Geschwindkeitsbegrenzung in Prozent</string>
|
<string name="frame_limit_slider">Geschwindkeitsbegrenzung in Prozent</string>
|
||||||
<string name="frame_limit_slider_description">Legt den Prozentsatz der Bergrenzung der Emulationsgeschwindigkeit fest. Mit dem Standardwert von 100% wird die Emulation auf die normale Geschwindigkeit begrenzt. Höhere oder niedrigere Werte erhöhen oder verringern die Geschwindigkeitsbegrenzung.</string>
|
<string name="frame_limit_slider_description">Gibt die prozentuale Geschwindigkeit der Emulation an. 100% sind normal. Werte darüber oder drunter werden die Geschwindigkeit entsprechend verändern.</string>
|
||||||
<string name="cpu_accuracy">CPU-Genauigkeit</string>
|
<string name="cpu_accuracy">CPU-Genauigkeit</string>
|
||||||
|
|
||||||
<!-- System settings strings -->
|
<!-- System settings strings -->
|
||||||
<string name="use_docked_mode">Dock-Modus</string>
|
<string name="use_docked_mode">Gedockter Modus</string>
|
||||||
<string name="use_docked_mode_description">Emuliert im Dock-Modus, was die Auflösung verbessert, aber die Leistung senkt.</string>
|
<string name="use_docked_mode_description">Der Docked Modus erhöht die Auflösung, verringert die aber die Leistung. Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die Leistung.</string>
|
||||||
<string name="emulated_region">Emulierte Region</string>
|
<string name="emulated_region">Emulierte Region</string>
|
||||||
<string name="emulated_language">Emulierte Sprache</string>
|
<string name="emulated_language">Emulierte Sprache</string>
|
||||||
<string name="select_rtc_date">RTC-Datum auswählen</string>
|
<string name="select_rtc_date">RTC-Datum auswählen</string>
|
||||||
<string name="select_rtc_time">RTC-Zeit auswählen</string>
|
<string name="select_rtc_time">RTC-Zeit auswählen</string>
|
||||||
<string name="use_custom_rtc">Benutzerdefinierte RTC aktivieren</string>
|
<string name="use_custom_rtc">Benutzerdefinierte Echtzeituhr</string>
|
||||||
<string name="use_custom_rtc_description">Mit dieser Einstellung kann eine benutzerdefinierte Echtzeituhr unabhängig von der aktuellen Systemzeit verwendet werden.</string>
|
|
||||||
<string name="set_custom_rtc">Benutzerdefinierte RTC einstellen</string>
|
|
||||||
|
|
||||||
<!-- Graphics settings strings -->
|
<!-- Graphics settings strings -->
|
||||||
<string name="renderer_api">API</string>
|
|
||||||
<string name="renderer_accuracy">Genauigkeitsstufe</string>
|
<string name="renderer_accuracy">Genauigkeitsstufe</string>
|
||||||
<string name="renderer_resolution">Auflösung</string>
|
|
||||||
<string name="renderer_vsync">VSync-Modus</string>
|
<string name="renderer_vsync">VSync-Modus</string>
|
||||||
|
<string name="renderer_screen_layout">Orientierung</string>
|
||||||
<string name="renderer_aspect_ratio">Seitenverhältnis</string>
|
<string name="renderer_aspect_ratio">Seitenverhältnis</string>
|
||||||
<string name="renderer_scaling_filter">Fensteranpassungsfilter</string>
|
<string name="renderer_scaling_filter">Fensteranpassungsfilter</string>
|
||||||
<string name="renderer_anti_aliasing">Kantenglättungs-Methode</string>
|
|
||||||
<string name="renderer_force_max_clock">Maximale Taktfrequenz erzwingen (nur Adreno)</string>
|
<string name="renderer_force_max_clock">Maximale Taktfrequenz erzwingen (nur Adreno)</string>
|
||||||
<string name="renderer_force_max_clock_description">Erzwingt den Betrieb der GPU mit der maximal möglichen Taktfrequenz (Temperaturbeschränkungen werden weiterhin angewendet).</string>
|
<string name="renderer_force_max_clock_description">Erzwingt den Betrieb der GPU mit der maximal möglichen Taktfrequenz (Temperaturbeschränkungen werden weiterhin angewendet).</string>
|
||||||
<string name="renderer_asynchronous_shaders">Asynchrone Shader nutzen</string>
|
<string name="renderer_asynchronous_shaders">Asynchrone Shader nutzen</string>
|
||||||
<string name="renderer_asynchronous_shaders_description">Kompiliert Shader asynchron, was Ruckler reduziert, aber zu Glitches führen kann.</string>
|
<!-- Debug settings strings -->
|
||||||
<string name="renderer_debug">Grafik-Debugging aktivieren</string>
|
<string name="cpu">CPU</string>
|
||||||
<string name="renderer_debug_description">Wenn aktiviert, schaltet die Grafik-API in einen langsameren Debugging-Modus.</string>
|
<string name="cpu_debug_mode">CPU Debugging</string>
|
||||||
<string name="use_disk_shader_cache">Nutze Festplatten-Shader-Cache</string>
|
<string name="gpu">GPU</string>
|
||||||
<string name="use_disk_shader_cache_description">Ruckeln wird durch das Speichern und Laden von generierten Shadern auf der Festplatte reduziert.</string>
|
<string name="renderer_api">API</string>
|
||||||
|
<string name="renderer_debug">Graphik-Debugging</string>
|
||||||
<!-- Audio settings strings -->
|
|
||||||
<string name="audio_volume">Lautstärke</string>
|
<string name="audio_volume">Lautstärke</string>
|
||||||
<string name="audio_volume_description">Legt die Lautstärke der Audioausgabe fest.</string>
|
<string name="audio_volume_description">Legt die Lautstärke der Audioausgabe fest.</string>
|
||||||
|
|
||||||
|
@ -154,14 +166,22 @@
|
||||||
<string name="ini_saved">Einstellungen gespeichert</string>
|
<string name="ini_saved">Einstellungen gespeichert</string>
|
||||||
<string name="gameid_saved">Einstellungen für %1$s gespeichert</string>
|
<string name="gameid_saved">Einstellungen für %1$s gespeichert</string>
|
||||||
<string name="error_saving">Fehler beim Speichern von %1$s.ini: %2$s</string>
|
<string name="error_saving">Fehler beim Speichern von %1$s.ini: %2$s</string>
|
||||||
|
<string name="unimplemented_menu">Unimplementiertes Menü</string>
|
||||||
<string name="loading">Lädt...</string>
|
<string name="loading">Lädt...</string>
|
||||||
<string name="reset_setting_confirmation">Möchtest du diese Einstellung auf den Standardwert zurücksetzen?</string>
|
<string name="reset_setting_confirmation">Möchtest du diese Einstellung auf den Standardwert zurücksetzen?</string>
|
||||||
<string name="reset_to_default">Auf Standard zurücksetzen</string>
|
<string name="reset_to_default">Auf Standard zurücksetzen</string>
|
||||||
<string name="reset_all_settings">Alle Einstellungen zurücksetzen?</string>
|
<string name="reset_all_settings">Alle Einstellungen zurücksetzen?</string>
|
||||||
<string name="reset_all_settings_description">Alle erweiterten Einstellungen werden auf ihren Standardwert zurückgesetzt. Dies kann nicht rückgängig gemacht werden.</string>
|
|
||||||
<string name="settings_reset">Einstellungen zurückgesetzt</string>
|
<string name="settings_reset">Einstellungen zurückgesetzt</string>
|
||||||
<string name="close">Schließen</string>
|
<string name="close">Schließen</string>
|
||||||
<string name="learn_more">Mehr erfahren</string>
|
<string name="learn_more">Mehr erfahren</string>
|
||||||
|
<string name="auto">Auto</string>
|
||||||
|
<string name="submit">Absenden</string>
|
||||||
|
<string name="string_null">Null</string>
|
||||||
|
<string name="string_import">Importieren</string>
|
||||||
|
<string name="export">Exportieren</string>
|
||||||
|
<string name="export_failed">Export fehlgeschlagen</string>
|
||||||
|
<string name="import_failed">Import fehlgeschlagen</string>
|
||||||
|
<string name="cancelling">Abbrechen</string>
|
||||||
|
|
||||||
<!-- GPU driver installation -->
|
<!-- GPU driver installation -->
|
||||||
<string name="select_gpu_driver">GPU-Treiber auswählen</string>
|
<string name="select_gpu_driver">GPU-Treiber auswählen</string>
|
||||||
|
@ -169,6 +189,7 @@
|
||||||
<string name="select_gpu_driver_install">Installieren</string>
|
<string name="select_gpu_driver_install">Installieren</string>
|
||||||
<string name="select_gpu_driver_default">Standard</string>
|
<string name="select_gpu_driver_default">Standard</string>
|
||||||
<string name="select_gpu_driver_use_default">Standard GPU-Treiber wird verwendet</string>
|
<string name="select_gpu_driver_use_default">Standard GPU-Treiber wird verwendet</string>
|
||||||
|
<string name="select_gpu_driver_error">Ungültiger Treiber ausgewählt, Standard-Treiber wird verwendet!</string>
|
||||||
<string name="system_gpu_driver">System GPU-Treiber</string>
|
<string name="system_gpu_driver">System GPU-Treiber</string>
|
||||||
<string name="installing_driver">Treiber wird installiert...</string>
|
<string name="installing_driver">Treiber wird installiert...</string>
|
||||||
|
|
||||||
|
@ -179,6 +200,7 @@
|
||||||
<string name="preferences_graphics">Grafik</string>
|
<string name="preferences_graphics">Grafik</string>
|
||||||
<string name="preferences_audio">Audio</string>
|
<string name="preferences_audio">Audio</string>
|
||||||
<string name="preferences_theme">Theme und Farbe</string>
|
<string name="preferences_theme">Theme und Farbe</string>
|
||||||
|
<string name="preferences_debug">Debug</string>
|
||||||
|
|
||||||
<!-- ROM loading errors -->
|
<!-- ROM loading errors -->
|
||||||
<string name="loader_error_encrypted">Das ROM ist verschlüsselt</string>
|
<string name="loader_error_encrypted">Das ROM ist verschlüsselt</string>
|
||||||
|
@ -192,22 +214,15 @@
|
||||||
<string name="emulation_exit">Emulation beenden</string>
|
<string name="emulation_exit">Emulation beenden</string>
|
||||||
<string name="emulation_done">Fertig</string>
|
<string name="emulation_done">Fertig</string>
|
||||||
<string name="emulation_fps_counter">FPS Zähler</string>
|
<string name="emulation_fps_counter">FPS Zähler</string>
|
||||||
<string name="emulation_toggle_controls">Steuerung umschalten</string>
|
|
||||||
<string name="emulation_rel_stick_center">Relative Stick-Mitte</string>
|
|
||||||
<string name="emulation_dpad_slide">DPad Slide</string>
|
|
||||||
<string name="emulation_haptics">Haptik</string>
|
|
||||||
<string name="emulation_show_overlay">Overlay anzeigen</string>
|
|
||||||
<string name="emulation_toggle_all">Alle umschalten</string>
|
<string name="emulation_toggle_all">Alle umschalten</string>
|
||||||
<string name="emulation_control_adjust">Overlay anpassen</string>
|
<string name="emulation_control_adjust">Overlay anpassen</string>
|
||||||
<string name="emulation_control_scale">Größe</string>
|
<string name="emulation_control_scale">Größe</string>
|
||||||
<string name="emulation_control_opacity">Transparenz</string>
|
<string name="emulation_control_opacity">Transparenz</string>
|
||||||
<string name="emulation_touch_overlay_reset">Overlay zurücksetzen</string>
|
<string name="emulation_touch_overlay_reset">Overlay zurücksetzen</string>
|
||||||
<string name="emulation_touch_overlay_edit">Overlay bearbeiten</string>
|
<string name="emulation_touch_overlay_edit">Overlay bearbeiten</string>
|
||||||
<string name="emulation_pause">Emulation pausieren</string>
|
|
||||||
<string name="emulation_unpause">Emulation fortsetzen</string>
|
|
||||||
<string name="emulation_input_overlay">Overlay-Optionen</string>
|
<string name="emulation_input_overlay">Overlay-Optionen</string>
|
||||||
|
|
||||||
<string name="load_settings">Lädt Einstellungen...</string>
|
<string name="load_settings">Lade Einstellungen...</string>
|
||||||
|
|
||||||
<!-- Software keyboard -->
|
<!-- Software keyboard -->
|
||||||
<string name="software_keyboard">Software-Tastatur</string>
|
<string name="software_keyboard">Software-Tastatur</string>
|
||||||
|
@ -221,7 +236,7 @@
|
||||||
<string name="fatal_error">Schwerwiegender Fehler</string>
|
<string name="fatal_error">Schwerwiegender Fehler</string>
|
||||||
<string name="fatal_error_message">Ein schwerwiegender Fehler ist aufgetreten. Einzelheiten wurden im Log protokolliert.\nDas Fortsetzen der Emulation kann zu Abstürzen und Bugs führen.</string>
|
<string name="fatal_error_message">Ein schwerwiegender Fehler ist aufgetreten. Einzelheiten wurden im Log protokolliert.\nDas Fortsetzen der Emulation kann zu Abstürzen und Bugs führen.</string>
|
||||||
<string name="performance_warning">Das Deaktivieren dieser Einstellung führt zu erheblichen Leistungsverlusten! Für ein optimales Erlebnis wird empfohlen, sie aktiviert zu lassen.</string>
|
<string name="performance_warning">Das Deaktivieren dieser Einstellung führt zu erheblichen Leistungsverlusten! Für ein optimales Erlebnis wird empfohlen, sie aktiviert zu lassen.</string>
|
||||||
|
<string name="memory_formatted">%1$s %2$s</string>
|
||||||
<!-- Region Names -->
|
<!-- Region Names -->
|
||||||
<string name="region_japan">Japan</string>
|
<string name="region_japan">Japan</string>
|
||||||
<string name="region_usa">USA</string>
|
<string name="region_usa">USA</string>
|
||||||
|
@ -231,6 +246,15 @@
|
||||||
<string name="region_korea">Korea</string>
|
<string name="region_korea">Korea</string>
|
||||||
<string name="region_taiwan">Taiwan</string>
|
<string name="region_taiwan">Taiwan</string>
|
||||||
|
|
||||||
|
<!-- Memory Sizes -->
|
||||||
|
<string name="memory_byte">Byte</string>
|
||||||
|
<string name="memory_kilobyte">KB</string>
|
||||||
|
<string name="memory_megabyte">MB</string>
|
||||||
|
<string name="memory_gigabyte">GB</string>
|
||||||
|
<string name="memory_terabyte">TB</string>
|
||||||
|
<string name="memory_petabyte">PB</string>
|
||||||
|
<string name="memory_exabyte">EB</string>
|
||||||
|
|
||||||
<!-- Renderer APIs -->
|
<!-- Renderer APIs -->
|
||||||
<string name="renderer_vulkan">Vulkan</string>
|
<string name="renderer_vulkan">Vulkan</string>
|
||||||
<string name="renderer_none">Keiner</string>
|
<string name="renderer_none">Keiner</string>
|
||||||
|
@ -267,12 +291,15 @@
|
||||||
<string name="anti_aliasing_fxaa">FXAA</string>
|
<string name="anti_aliasing_fxaa">FXAA</string>
|
||||||
<string name="anti_aliasing_smaa">SMAA</string>
|
<string name="anti_aliasing_smaa">SMAA</string>
|
||||||
|
|
||||||
|
<string name="screen_layout_portrait">Portrait</string>
|
||||||
|
<string name="screen_layout_auto">Auto</string>
|
||||||
|
|
||||||
<!-- Aspect Ratios -->
|
<!-- Aspect Ratios -->
|
||||||
<string name="ratio_default">Standard (16:9)</string>
|
<string name="ratio_default">Standard (16:9)</string>
|
||||||
<string name="ratio_force_four_three">4:3 erzwingen</string>
|
<string name="ratio_force_four_three">4:3 erzwingen</string>
|
||||||
<string name="ratio_force_twenty_one_nine">21:9 erzwingen</string>
|
<string name="ratio_force_twenty_one_nine">21:9 erzwingen</string>
|
||||||
<string name="ratio_force_sixteen_ten">Erzwinge 16:10</string>
|
<string name="ratio_force_sixteen_ten">Erzwinge 16:10</string>
|
||||||
<string name="ratio_stretch">Auf Fenster anpassen</string>
|
<string name="ratio_stretch">Auf Bildschirmgröße anpsassen</string>
|
||||||
|
|
||||||
<!-- CPU Accuracy -->
|
<!-- CPU Accuracy -->
|
||||||
<string name="cpu_accuracy_accurate">Akkurat</string>
|
<string name="cpu_accuracy_accurate">Akkurat</string>
|
||||||
|
@ -280,9 +307,9 @@
|
||||||
<string name="cpu_accuracy_paranoid">Paranoid (Langsam)</string>
|
<string name="cpu_accuracy_paranoid">Paranoid (Langsam)</string>
|
||||||
|
|
||||||
<!-- Gamepad Buttons -->
|
<!-- Gamepad Buttons -->
|
||||||
<string name="gamepad_d_pad">Steuerkreuz</string>
|
<string name="gamepad_d_pad">D-Pad</string>
|
||||||
<string name="gamepad_left_stick">Linker Analogstick</string>
|
<string name="gamepad_left_stick">Linker Stick</string>
|
||||||
<string name="gamepad_right_stick">Rechter Analogstick</string>
|
<string name="gamepad_right_stick">Rechter Stick</string>
|
||||||
<string name="gamepad_home">Home</string>
|
<string name="gamepad_home">Home</string>
|
||||||
<string name="gamepad_screenshot">Screenshot</string>
|
<string name="gamepad_screenshot">Screenshot</string>
|
||||||
|
|
||||||
|
@ -291,18 +318,30 @@
|
||||||
<string name="building_shaders">Shader werden erstellt</string>
|
<string name="building_shaders">Shader werden erstellt</string>
|
||||||
|
|
||||||
<!-- Theme options -->
|
<!-- Theme options -->
|
||||||
<string name="change_app_theme">App-Theme ändern</string>
|
<string name="change_app_theme">App-Thema ändern</string>
|
||||||
<string name="theme_default">Standard</string>
|
<string name="theme_default">Standard</string>
|
||||||
<string name="theme_material_you">Material You</string>
|
<string name="theme_material_you">Material You</string>
|
||||||
|
|
||||||
<!-- Theme Modes -->
|
<!-- Theme Modes -->
|
||||||
<string name="change_theme_mode">Theme-Modus ändern</string>
|
<string name="change_theme_mode">Themen-Modus ändern</string>
|
||||||
<string name="theme_mode_follow_system">System folgen</string>
|
<string name="theme_mode_follow_system">System folgen</string>
|
||||||
<string name="theme_mode_light">Hell</string>
|
<string name="theme_mode_light">Hell</string>
|
||||||
<string name="theme_mode_dark">Dunkel</string>
|
<string name="theme_mode_dark">Dunkel</string>
|
||||||
|
|
||||||
|
<!-- Audio output engines -->
|
||||||
|
<string name="cubeb">cubeb</string>
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Schwarze Hintergünde verwenden</string>
|
<string name="use_black_backgrounds">Schwarze Hintergründe</string>
|
||||||
<string name="use_black_backgrounds_description">Bei Verwendung des dunklen Themes, schwarze Hintergründe verwenden.</string>
|
<string name="use_black_backgrounds_description">Bei Verwendung des dunklen Themes, schwarze Hintergründe verwenden.</string>
|
||||||
|
|
||||||
|
<!-- Picture-In-Picture -->
|
||||||
|
<string name="picture_in_picture">Bild im Bild</string>
|
||||||
|
<string name="pause">Pause</string>
|
||||||
|
<string name="mute">Stummschalten</string>
|
||||||
|
<string name="unmute">Ton aktivieren</string>
|
||||||
|
|
||||||
|
<!-- Licenses screen strings -->
|
||||||
|
<string name="licenses">Lizenzen</string>
|
||||||
|
<string name="license_fidelityfx_fsr_description">Hochwertiges Upscaling von AMD</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||||
|
|
||||||
<string name="app_disclaimer">Este software ejecuta juegos para la videoconsola Nintendo Switch. Los videojuegos o keys no vienen incluidos.<br /><br />Antes de empezar, por favor, localice el archivo <![CDATA[<b> prod.keys </b>]]>en el almacenamiento de su dispositivo..<br /><br /><![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Saber más</a>]]></string>
|
<string name="app_disclaimer">Este software ejecuta juegos para la videoconsola Nintendo Switch. Los videojuegos o claves no vienen incluidos.<br /><br />Antes de empezar, por favor, localice el archivo <![CDATA[<b> prod.keys </b>]]>en el almacenamiento de su dispositivo..<br /><br /><![CDATA[<a href=\"https://yuzu-emu.org/help/quickstart\">Saber más</a>]]></string>
|
||||||
<string name="emulation_notification_channel_name">Emulación activa</string>
|
<string name="emulation_notification_channel_name">Emulación activa</string>
|
||||||
<string name="emulation_notification_channel_description">Muestra una notificación persistente cuando la emulación está activa.</string>
|
<string name="emulation_notification_channel_description">Muestra una notificación persistente cuando la emulación está activa.</string>
|
||||||
<string name="emulation_notification_running">yuzu esta ejecutándose</string>
|
<string name="emulation_notification_running">yuzu esta ejecutándose</string>
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
<string name="back">Atrás</string>
|
<string name="back">Atrás</string>
|
||||||
<string name="add_games">Añadir Juegos</string>
|
<string name="add_games">Añadir Juegos</string>
|
||||||
<string name="add_games_description">Selecciona la carpeta de juegos</string>
|
<string name="add_games_description">Selecciona la carpeta de juegos</string>
|
||||||
|
<string name="step_complete">¡Completado!</string>
|
||||||
|
|
||||||
<!-- Home strings -->
|
<!-- Home strings -->
|
||||||
<string name="home_games">Juegos</string>
|
<string name="home_games">Juegos</string>
|
||||||
|
@ -37,7 +38,8 @@
|
||||||
<string name="add_games_warning">¿Omitir la selección de la carpeta de juegos?</string>
|
<string name="add_games_warning">¿Omitir la selección de la carpeta de juegos?</string>
|
||||||
<string name="add_games_warning_description">No se mostrará ningún juego si no se ha seleccionado una carpeta de juegos.</string>
|
<string name="add_games_warning_description">No se mostrará ningún juego si no se ha seleccionado una carpeta de juegos.</string>
|
||||||
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
|
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
|
||||||
<string name="home_search_games">Buscar Juegos</string>
|
<string name="home_search_games">Buscar juegos</string>
|
||||||
|
<string name="search_settings">Buscar configuración</string>
|
||||||
<string name="games_dir_selected">Directorio de juegos seleccionado</string>
|
<string name="games_dir_selected">Directorio de juegos seleccionado</string>
|
||||||
<string name="install_prod_keys">Instalar prod.keys</string>
|
<string name="install_prod_keys">Instalar prod.keys</string>
|
||||||
<string name="install_prod_keys_description">Requerido para descifrar juegos</string>
|
<string name="install_prod_keys_description">Requerido para descifrar juegos</string>
|
||||||
|
@ -58,15 +60,18 @@
|
||||||
<string name="warning_cancel">Cancelar</string>
|
<string name="warning_cancel">Cancelar</string>
|
||||||
<string name="install_amiibo_keys">Instalar clave de Amiiboo</string>
|
<string name="install_amiibo_keys">Instalar clave de Amiiboo</string>
|
||||||
<string name="install_amiibo_keys_description">Necesario para usar Amiibo en el juego</string>
|
<string name="install_amiibo_keys_description">Necesario para usar Amiibo en el juego</string>
|
||||||
<string name="invalid_keys_file">Archivo de claves inválido seleccionado</string>
|
<string name="invalid_keys_file">Archivo de claves seleccionado inválido</string>
|
||||||
<string name="install_keys_success">Claves instaladas correctamente</string>
|
<string name="install_keys_success">Claves instaladas correctamente</string>
|
||||||
<string name="reading_keys_failure">Error al leer las claves de cifrado</string>
|
<string name="reading_keys_failure">Error al leer las claves de cifrado</string>
|
||||||
|
<string name="install_prod_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .keys y pruebe otra vez.</string>
|
||||||
|
<string name="install_amiibo_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .bin y pruebe otra vez.</string>
|
||||||
<string name="invalid_keys_error">Claves de cifrado no válidas</string>
|
<string name="invalid_keys_error">Claves de cifrado no válidas</string>
|
||||||
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
|
<string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string>
|
||||||
<string name="install_keys_failure_description">El archivo seleccionado es incorrecto o está corrupto. Vuelva a redumpear sus claves.</string>
|
<string name="install_keys_failure_description">El archivo seleccionado es incorrecto o está corrupto. Vuelva a redumpear sus claves.</string>
|
||||||
<string name="install_gpu_driver">Instalar driver de GPU</string>
|
<string name="install_gpu_driver">Instalar driver de GPU</string>
|
||||||
<string name="install_gpu_driver_description">Instale drivers alternativos para obtener un rendimiento o una precisión potencialmente mejores</string>
|
<string name="install_gpu_driver_description">Instale drivers alternativos para obtener un rendimiento o una precisión potencialmente mejores</string>
|
||||||
<string name="advanced_settings">Opciones avanzadas</string>
|
<string name="advanced_settings">Opciones avanzadas</string>
|
||||||
|
<string name="advanced_settings_game">Configuración avanzada: %1$s</string>
|
||||||
<string name="settings_description">Configurar las opciones del emulador</string>
|
<string name="settings_description">Configurar las opciones del emulador</string>
|
||||||
<string name="search_recently_played">Jugado recientemente</string>
|
<string name="search_recently_played">Jugado recientemente</string>
|
||||||
<string name="search_recently_added">Añadido recientemente</string>
|
<string name="search_recently_added">Añadido recientemente</string>
|
||||||
|
@ -86,6 +91,33 @@
|
||||||
<string name="save_file_invalid_zip_structure_description">El nombre de la primera subcarpeta debe ser el Title ID del juego.</string>
|
<string name="save_file_invalid_zip_structure_description">El nombre de la primera subcarpeta debe ser el Title ID del juego.</string>
|
||||||
<string name="import_saves">Importar</string>
|
<string name="import_saves">Importar</string>
|
||||||
<string name="export_saves">Exportar</string>
|
<string name="export_saves">Exportar</string>
|
||||||
|
<string name="install_firmware">Instalar firmware</string>
|
||||||
|
<string name="install_firmware_description">El firmware debe estar en un archivo ZIP y es necesario para ejecutar algunos juegos</string>
|
||||||
|
<string name="firmware_installing">Instalando firmware</string>
|
||||||
|
<string name="firmware_installed_success">Firmware instalado con éxito</string>
|
||||||
|
<string name="firmware_installed_failure">Falló la instalación de firmware</string>
|
||||||
|
<string name="firmware_installed_failure_description">Asegúrese de que los archivos nca del firmware estén en la raíz del zip e inténtelo de nuevo.</string>
|
||||||
|
<string name="share_log">Compartir registros de depuración</string>
|
||||||
|
<string name="share_log_description">Comparta el archivo de registro de yuzu para depurar problemas</string>
|
||||||
|
<string name="share_log_missing">No se encontró ningún archivo de registro</string>
|
||||||
|
<string name="install_game_content">Instalar contenido de juego</string>
|
||||||
|
<string name="install_game_content_description">Instalar actualizaciones o DLC</string>
|
||||||
|
<string name="installing_game_content">Instalando contenido...</string>
|
||||||
|
<string name="install_game_content_failure">Error instalando archivo(s) a la NAND</string>
|
||||||
|
<string name="install_game_content_failure_description">Asegúrese de que el/los contenido(s) son válidos y que el archivo prod.keys esté instalado.</string>
|
||||||
|
<string name="install_game_content_failure_base">La instalación de los juegos base no está permitida para así evitar posibles conflictos.</string>
|
||||||
|
<string name="install_game_content_failure_file_extension">Sólo hay soporte para el contenido en NSP y XCI. Asegúrese de que el/los contenido(s) son válidos.</string>
|
||||||
|
<string name="install_game_content_failed_count">%1$d error(es) de instalación</string>
|
||||||
|
<string name="install_game_content_success">Contenido(s) de juego instalado/s con éxito</string>
|
||||||
|
<string name="install_game_content_success_install">%1$d instalado con éxito</string>
|
||||||
|
<string name="install_game_content_success_overwrite">%1$d sobreescrito con éxito</string>
|
||||||
|
<string name="install_game_content_help_link">https://yuzu-emu.org/help/quickstart/#dumping-installed-updates</string>
|
||||||
|
<string name="custom_driver_not_supported">Drivers personalizados no soportados</string>
|
||||||
|
<string name="custom_driver_not_supported_description">En estos momentos, la carga de drivers personalizados no está disponible para este dispositivo..\n¡Comprueba esta opción en el futuro para ver si ya está añadido el soporte a ese dispositivo!</string>
|
||||||
|
<string name="manage_yuzu_data">Administrar datos de yuzu</string>
|
||||||
|
<string name="manage_yuzu_data_description">Importa/exporta el firmware, las keys, los datos de usuario, ¡y más!</string>
|
||||||
|
<string name="share_save_file">Compartir archivo de guardado</string>
|
||||||
|
<string name="export_save_failed">La exportación del guardado falló</string>
|
||||||
|
|
||||||
<!-- About screen strings -->
|
<!-- About screen strings -->
|
||||||
<string name="gaia_is_not_real">Gaia no es real</string>
|
<string name="gaia_is_not_real">Gaia no es real</string>
|
||||||
|
@ -94,7 +126,18 @@
|
||||||
<string name="contributors">Contribuidores</string>
|
<string name="contributors">Contribuidores</string>
|
||||||
<string name="contributors_description">Hecho con \u2764 del equipo yuzu</string>
|
<string name="contributors_description">Hecho con \u2764 del equipo yuzu</string>
|
||||||
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
|
<string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
|
||||||
|
<string name="licenses_description">Proyectos que hacen que yuzu para Android sea una realidad</string>
|
||||||
<string name="build">Versión</string>
|
<string name="build">Versión</string>
|
||||||
|
<string name="user_data">Datos de usuario</string>
|
||||||
|
<string name="user_data_description">Importa/exporta todos los datos de usuario.\n\nCuando se importen los datos de usuario, ¡los demás datos de usuario existentes serán borrados!</string>
|
||||||
|
<string name="exporting_user_data">Exportando datos de usuario...</string>
|
||||||
|
<string name="importing_user_data">Importando datos de usuario...</string>
|
||||||
|
<string name="import_user_data">Importar datos de usuario</string>
|
||||||
|
<string name="invalid_yuzu_backup">Backup de válido</string>
|
||||||
|
<string name="user_data_export_success">Datos de usuario exportados con éxito</string>
|
||||||
|
<string name="user_data_import_success">Datos de usuario importados con éxito</string>
|
||||||
|
<string name="user_data_export_cancelled">Exportación cancelada</string>
|
||||||
|
<string name="user_data_import_failed_description">Asegúrese de que las carpetas de datos de usuario estén en la raíz de la carpeta del zip y contengan un archivo config en config/config.ini e inténtelo de nuevo.</string>
|
||||||
<string name="support_link">https://discord.gg/u77vRWY</string>
|
<string name="support_link">https://discord.gg/u77vRWY</string>
|
||||||
<string name="website_link">https://yuzu-emu.org/</string>
|
<string name="website_link">https://yuzu-emu.org/</string>
|
||||||
<string name="github_link">https://github.com/yuzu-emu</string>
|
<string name="github_link">https://github.com/yuzu-emu</string>
|
||||||
|
@ -114,41 +157,53 @@
|
||||||
<string name="are_you_interested">¿Estás interesado?</string>
|
<string name="are_you_interested">¿Estás interesado?</string>
|
||||||
|
|
||||||
<!-- General settings strings -->
|
<!-- General settings strings -->
|
||||||
<string name="frame_limit_enable">Activar limite de velocidad</string>
|
<string name="frame_limit_enable">Limitar velocidad</string>
|
||||||
<string name="frame_limit_enable_description">Cuando está habilitado, la velocidad de emulación se limitará a un porcentaje específico de la velocidad normal.</string>
|
<string name="frame_limit_enable_description">Limita la velocidad de emulación a un porcentaje específico de la velocidad normal.</string>
|
||||||
<string name="frame_limit_slider">Limitar porcentaje de velocidad</string>
|
<string name="frame_limit_slider">Limitar porcentaje de velocidad</string>
|
||||||
<string name="frame_limit_slider_description">Especifica el porcentaje para limitar la velocidad de emulación. Con el valor predeterminado del 100 %, la emulación se limitará a la velocidad normal. Valores más altos o más bajos aumentarán o disminuirán el límite de velocidad.</string>
|
<string name="frame_limit_slider_description">Especifica el porcentaje para limitar la velocidad de emulación. 100% es la velocidad normal. Valores más altos o bajos incrementarán o disminuirán el límite de velocidad.</string>
|
||||||
<string name="cpu_accuracy">Precisión de CPU</string>
|
<string name="cpu_accuracy">Precisión de CPU</string>
|
||||||
|
<string name="value_with_units">%1$s%2$s</string>
|
||||||
|
|
||||||
<!-- System settings strings -->
|
<!-- System settings strings -->
|
||||||
<string name="use_docked_mode">Modo sobremesa</string>
|
<string name="use_docked_mode">Modo Sobremesa</string>
|
||||||
<string name="use_docked_mode_description">Emula en modo sobremesa, lo que aumenta la resolución perjudicando el rendimiento.</string>
|
<string name="use_docked_mode_description">Incrementa la resolución al coste de reducir el rendimiento. El Modo Portátil es usado cuando está desactivado, reduciendo la resolución y mejorando así el rendimiento.</string>
|
||||||
<string name="emulated_region">Región emulada</string>
|
<string name="emulated_region">Región emulada</string>
|
||||||
<string name="emulated_language">Idioma emulado</string>
|
<string name="emulated_language">Idioma emulado</string>
|
||||||
<string name="select_rtc_date">Seleccionar Fecha RTC</string>
|
<string name="select_rtc_date">Seleccionar fecha RTC</string>
|
||||||
<string name="select_rtc_time">Seleccionar Tiempo RTC</string>
|
<string name="select_rtc_time">Seleccionar tiempo RTC</string>
|
||||||
<string name="use_custom_rtc">Habilitar RTC Personalizado</string>
|
<string name="use_custom_rtc">RTC personalizado</string>
|
||||||
<string name="use_custom_rtc_description">Esta configuración le permite configurar un reloj de tiempo real personalizado diferente a la hora actual de su sistema</string>
|
<string name="use_custom_rtc_description">Te permite tener un reloj personalizado en tiempo real diferente del tiempo del propio sistema.</string>
|
||||||
<string name="set_custom_rtc">Establecer RTC Personalizado</string>
|
<string name="set_custom_rtc">Configurar RTC personalizado</string>
|
||||||
|
|
||||||
<!-- Graphics settings strings -->
|
<!-- Graphics settings strings -->
|
||||||
<string name="renderer_api">API</string>
|
|
||||||
<string name="renderer_accuracy">Nivel de precisión</string>
|
<string name="renderer_accuracy">Nivel de precisión</string>
|
||||||
<string name="renderer_resolution">Resolución</string>
|
<string name="renderer_resolution">Resolución (Portátil/Sobremesa)</string>
|
||||||
<string name="renderer_vsync">Modo VSync</string>
|
<string name="renderer_vsync">Modo VSync</string>
|
||||||
|
<string name="renderer_screen_layout">Orientación</string>
|
||||||
<string name="renderer_aspect_ratio">Relación de aspecto</string>
|
<string name="renderer_aspect_ratio">Relación de aspecto</string>
|
||||||
<string name="renderer_scaling_filter">Filtro de adaptación de ventana</string>
|
<string name="renderer_scaling_filter">Filtro de adaptación de ventana</string>
|
||||||
<string name="renderer_anti_aliasing">Metodo Anti Aliasing</string>
|
<string name="renderer_anti_aliasing">Método anti-aliasing</string>
|
||||||
<string name="renderer_force_max_clock">Forzar velocidad al máximo (solo Adreno)</string>
|
<string name="renderer_force_max_clock">Forzar velocidad al máximo (solo Adreno)</string>
|
||||||
<string name="renderer_force_max_clock_description">Fuerza a la GPU a ejecutarse a la velocidad máxima de reloj posible (se seguirán aplicando restricciones térmicas).</string>
|
<string name="renderer_force_max_clock_description">Fuerza a la GPU a ejecutarse a la velocidad máxima de reloj posible (se seguirán aplicando restricciones térmicas).</string>
|
||||||
<string name="renderer_asynchronous_shaders">Usar shaders asíncronos</string>
|
<string name="renderer_asynchronous_shaders">Usar shaders asíncronos</string>
|
||||||
<string name="renderer_asynchronous_shaders_description">Compila shaders de forma asincrónica, lo que reducirá los parones pero puede introducir fallos.</string>
|
<string name="renderer_asynchronous_shaders_description">Compila shaders de manera asíncrona, reduciendo los parones, pero puede introducir fallos.</string>
|
||||||
<string name="renderer_debug">Habilitar la depuración de gráficos</string>
|
<string name="renderer_reactive_flushing">Usar limpieza reactiva</string>
|
||||||
<string name="renderer_debug_description">Cuando esté marcado, la API de gráficos entra en un modo de depuración más lento.</string>
|
<string name="renderer_reactive_flushing_description">Mejora la precisión de renderizado en algunos juegos, pero reduce el rendimiento.</string>
|
||||||
<string name="use_disk_shader_cache">Usar caché de shaders en disco</string>
|
<string name="use_disk_shader_cache">Caché de shaders en disco</string>
|
||||||
<string name="use_disk_shader_cache_description">Reduzca los parones almacenando y cargando shaders generados en el disco.</string>
|
<string name="use_disk_shader_cache_description">Reduce los parones almacenando y cargando shaders generados.</string>
|
||||||
|
|
||||||
|
<!-- Debug settings strings -->
|
||||||
|
<string name="cpu">CPU</string>
|
||||||
|
<string name="cpu_debug_mode">Depuración de CPU</string>
|
||||||
|
<string name="cpu_debug_mode_description">Pone la CPU en un modo de depuración lento.</string>
|
||||||
|
<string name="gpu">GPU</string>
|
||||||
|
<string name="renderer_api">API</string>
|
||||||
|
<string name="renderer_debug">Depuración de gráficos</string>
|
||||||
|
<string name="renderer_debug_description">Configura la API gráfica a un modo de depuración lento.</string>
|
||||||
|
<string name="fastmem">Fastmem</string>
|
||||||
|
|
||||||
<!-- Audio settings strings -->
|
<!-- Audio settings strings -->
|
||||||
|
<string name="audio_output_engine">Motor de salida</string>
|
||||||
<string name="audio_volume">Volumen</string>
|
<string name="audio_volume">Volumen</string>
|
||||||
<string name="audio_volume_description">Especifica el volumen de la salida de audio.</string>
|
<string name="audio_volume_description">Especifica el volumen de la salida de audio.</string>
|
||||||
|
|
||||||
|
@ -157,14 +212,24 @@
|
||||||
<string name="ini_saved">Configuración guardada</string>
|
<string name="ini_saved">Configuración guardada</string>
|
||||||
<string name="gameid_saved">Configuración guardada para %1$s</string>
|
<string name="gameid_saved">Configuración guardada para %1$s</string>
|
||||||
<string name="error_saving">Error guardando %1$s.ini: %2$s</string>
|
<string name="error_saving">Error guardando %1$s.ini: %2$s</string>
|
||||||
|
<string name="unimplemented_menu">Menú sin implementar</string>
|
||||||
<string name="loading">Cargando...</string>
|
<string name="loading">Cargando...</string>
|
||||||
|
<string name="shutting_down">Saliendo...</string>
|
||||||
<string name="reset_setting_confirmation">¿Desea restablecer esta configuración a su valor predeterminado?</string>
|
<string name="reset_setting_confirmation">¿Desea restablecer esta configuración a su valor predeterminado?</string>
|
||||||
<string name="reset_to_default">Restablecer a predeterminado</string>
|
<string name="reset_to_default">Restablecer a predeterminado</string>
|
||||||
<string name="reset_all_settings">¿Restablecer todas las configuraciones?</string>
|
<string name="reset_all_settings">¿Restablecer todas las configuraciones?</string>
|
||||||
<string name="reset_all_settings_description">Todas las configuraciones avanzadas se restablecerán a su configuración predeterminada. Esto no se puede deshacer.</string>
|
<string name="reset_all_settings_description">Todas las opciones avanzadas se restablecerán a su configuración predeterminada. Esta acción no se puede deshacer.</string>
|
||||||
<string name="settings_reset">Reiniciar la configuracion</string>
|
<string name="settings_reset">Reiniciar la configuracion</string>
|
||||||
<string name="close">Cerrar</string>
|
<string name="close">Cerrar</string>
|
||||||
<string name="learn_more">Más información</string>
|
<string name="learn_more">Saber más</string>
|
||||||
|
<string name="auto">Auto</string>
|
||||||
|
<string name="submit">Enviar</string>
|
||||||
|
<string name="string_null">Null</string>
|
||||||
|
<string name="string_import">Importar</string>
|
||||||
|
<string name="export">Exportar</string>
|
||||||
|
<string name="export_failed">La exportación falló</string>
|
||||||
|
<string name="import_failed">La importación falló</string>
|
||||||
|
<string name="cancelling">Cancelando</string>
|
||||||
|
|
||||||
<!-- GPU driver installation -->
|
<!-- GPU driver installation -->
|
||||||
<string name="select_gpu_driver">Seleccionar driver GPU</string>
|
<string name="select_gpu_driver">Seleccionar driver GPU</string>
|
||||||
|
@ -172,6 +237,7 @@
|
||||||
<string name="select_gpu_driver_install">Instalar</string>
|
<string name="select_gpu_driver_install">Instalar</string>
|
||||||
<string name="select_gpu_driver_default">Predeterminado</string>
|
<string name="select_gpu_driver_default">Predeterminado</string>
|
||||||
<string name="select_gpu_driver_use_default">Usando el driver de GPU por defecto </string>
|
<string name="select_gpu_driver_use_default">Usando el driver de GPU por defecto </string>
|
||||||
|
<string name="select_gpu_driver_error">¡Driver no válido, utilizando el predeterminado del sistema!</string>
|
||||||
<string name="system_gpu_driver">Driver GPU del sistema</string>
|
<string name="system_gpu_driver">Driver GPU del sistema</string>
|
||||||
<string name="installing_driver">Instalando driver...</string>
|
<string name="installing_driver">Instalando driver...</string>
|
||||||
|
|
||||||
|
@ -182,10 +248,11 @@
|
||||||
<string name="preferences_graphics">Gráficos</string>
|
<string name="preferences_graphics">Gráficos</string>
|
||||||
<string name="preferences_audio">Audio</string>
|
<string name="preferences_audio">Audio</string>
|
||||||
<string name="preferences_theme">Tema y color</string>
|
<string name="preferences_theme">Tema y color</string>
|
||||||
|
<string name="preferences_debug">Depuración</string>
|
||||||
|
|
||||||
<!-- ROM loading errors -->
|
<!-- ROM loading errors -->
|
||||||
<string name="loader_error_encrypted">Su ROM está encriptada</string>
|
<string name="loader_error_encrypted">Su ROM está encriptada</string>
|
||||||
<string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga las guías para redumpear <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-cartridge-games\">cartuchos de juegos</a> o <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-installed-titles-eshop\">titulos instalados</a>.]]></string>
|
<string name="loader_error_encrypted_roms_description"><![CDATA[Por favor, siga las guías para redumpear<a href=\"https://yuzu-emu.org/help/quickstart/#dumping-physical-titles-game-cards\">cartuchos de juegos</a> o <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-digital-titles-eshop\">títulos instalados</a>.]]></string>
|
||||||
<string name="loader_error_encrypted_keys_description"><![CDATA[Por favor, compruebe que su archivo <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado, para que los juegos sean descifrados.]]></string>
|
<string name="loader_error_encrypted_keys_description"><![CDATA[Por favor, compruebe que su archivo <a href=\"https://yuzu-emu.org/help/quickstart/#dumping-prodkeys-and-titlekeys\">prod.keys</a> está instalado, para que los juegos sean descifrados.]]></string>
|
||||||
<string name="loader_error_video_core">Ocurrió un error al inicializar el núcleo de video, posiblemente debido a una incompatibilidad con el driver seleccionado</string>
|
<string name="loader_error_video_core">Ocurrió un error al inicializar el núcleo de video, posiblemente debido a una incompatibilidad con el driver seleccionado</string>
|
||||||
<string name="loader_error_video_core_description">Esto suele deberse a un driver de GPU incompatible. La instalación de un controlador de GPU personalizado puede resolver este problema.</string>
|
<string name="loader_error_video_core_description">Esto suele deberse a un driver de GPU incompatible. La instalación de un controlador de GPU personalizado puede resolver este problema.</string>
|
||||||
|
@ -196,25 +263,25 @@
|
||||||
<string name="emulation_exit">Salir de la emulación</string>
|
<string name="emulation_exit">Salir de la emulación</string>
|
||||||
<string name="emulation_done">Hecho</string>
|
<string name="emulation_done">Hecho</string>
|
||||||
<string name="emulation_fps_counter">Contador de FPS</string>
|
<string name="emulation_fps_counter">Contador de FPS</string>
|
||||||
<string name="emulation_toggle_controls">Alternar Controles</string>
|
<string name="emulation_toggle_controls">Alternar controles</string>
|
||||||
<string name="emulation_rel_stick_center">Centro Relativo del Stick</string>
|
<string name="emulation_rel_stick_center">Centro relativo del stick</string>
|
||||||
<string name="emulation_dpad_slide">Deslizamiento de la Cruceta</string>
|
<string name="emulation_dpad_slide">Deslizamiento de la cruceta</string>
|
||||||
<string name="emulation_haptics">Hápticos</string>
|
<string name="emulation_haptics">Toques hápticos</string>
|
||||||
<string name="emulation_show_overlay">Mostrar pantalla</string>
|
<string name="emulation_show_overlay">Mostrar overlay</string>
|
||||||
<string name="emulation_toggle_all">Alternar Todo</string>
|
<string name="emulation_toggle_all">Alternar todo</string>
|
||||||
<string name="emulation_control_adjust">Ajustar pantalla</string>
|
<string name="emulation_control_adjust">Ajustar overlay</string>
|
||||||
<string name="emulation_control_scale">Escala</string>
|
<string name="emulation_control_scale">Escala</string>
|
||||||
<string name="emulation_control_opacity">Opacidad</string>
|
<string name="emulation_control_opacity">Opacidad</string>
|
||||||
<string name="emulation_touch_overlay_reset">Reiniciar pantalla</string>
|
<string name="emulation_touch_overlay_reset">Reiniciar overlay</string>
|
||||||
<string name="emulation_touch_overlay_edit">Editar pantalla</string>
|
<string name="emulation_touch_overlay_edit">Editar overlay</string>
|
||||||
<string name="emulation_pause">Pausar Emulación</string>
|
<string name="emulation_pause">Pausar emulación</string>
|
||||||
<string name="emulation_unpause">Reanudar Emulación</string>
|
<string name="emulation_unpause">Despausar emulación</string>
|
||||||
<string name="emulation_input_overlay">Opciones de pantalla </string>
|
<string name="emulation_input_overlay">Opciones de overlay</string>
|
||||||
|
|
||||||
<string name="load_settings">Cargando configuración...</string>
|
<string name="load_settings">Cargando configuración...</string>
|
||||||
|
|
||||||
<!-- Software keyboard -->
|
<!-- Software keyboard -->
|
||||||
<string name="software_keyboard">Software del teclado</string>
|
<string name="software_keyboard">Teclado de software</string>
|
||||||
|
|
||||||
<!-- Errors and warnings -->
|
<!-- Errors and warnings -->
|
||||||
<string name="abort_button">Abortar</string>
|
<string name="abort_button">Abortar</string>
|
||||||
|
@ -226,6 +293,9 @@
|
||||||
<string name="fatal_error">Error fatal</string>
|
<string name="fatal_error">Error fatal</string>
|
||||||
<string name="fatal_error_message">Ocurrió un error fatal. Consulte el registro para obtener más detalles.\nContinuar con la emulación puede provocar bloqueos y errores.</string>
|
<string name="fatal_error_message">Ocurrió un error fatal. Consulte el registro para obtener más detalles.\nContinuar con la emulación puede provocar bloqueos y errores.</string>
|
||||||
<string name="performance_warning">¡Desactivar esta configuración reducirá significativamente el rendimiento de la emulación! Para obtener la mejor experiencia, se recomienda dejar esta configuración habilitada.</string>
|
<string name="performance_warning">¡Desactivar esta configuración reducirá significativamente el rendimiento de la emulación! Para obtener la mejor experiencia, se recomienda dejar esta configuración habilitada.</string>
|
||||||
|
<string name="device_memory_inadequate">RAM de dispositivo: %1$s\nRecomendado: %2$s</string>
|
||||||
|
<string name="memory_formatted">%1$s %2$s</string>
|
||||||
|
<string name="no_game_present">¡No hay ningún juego ejecutable presente!</string>
|
||||||
|
|
||||||
<!-- Region Names -->
|
<!-- Region Names -->
|
||||||
<string name="region_japan">Japón</string>
|
<string name="region_japan">Japón</string>
|
||||||
|
@ -236,7 +306,14 @@
|
||||||
<string name="region_korea">Corea</string>
|
<string name="region_korea">Corea</string>
|
||||||
<string name="region_taiwan">Taiwán</string>
|
<string name="region_taiwan">Taiwán</string>
|
||||||
|
|
||||||
<!-- Language Names -->
|
<!-- Memory Sizes -->
|
||||||
|
<string name="memory_byte">Byte</string>
|
||||||
|
<string name="memory_kilobyte">KB</string>
|
||||||
|
<string name="memory_megabyte">MB</string>
|
||||||
|
<string name="memory_gigabyte">GB</string>
|
||||||
|
<string name="memory_terabyte">TB</string>
|
||||||
|
<string name="memory_petabyte">PB</string>
|
||||||
|
<string name="memory_exabyte">EB</string>
|
||||||
|
|
||||||
<!-- Renderer APIs -->
|
<!-- Renderer APIs -->
|
||||||
<string name="renderer_vulkan">Vulkan</string>
|
<string name="renderer_vulkan">Vulkan</string>
|
||||||
|
@ -274,6 +351,11 @@
|
||||||
<string name="anti_aliasing_fxaa">FXAA</string>
|
<string name="anti_aliasing_fxaa">FXAA</string>
|
||||||
<string name="anti_aliasing_smaa">SMAA</string>
|
<string name="anti_aliasing_smaa">SMAA</string>
|
||||||
|
|
||||||
|
<!-- Screen Layouts -->
|
||||||
|
<string name="screen_layout_landscape">Paisaje</string>
|
||||||
|
<string name="screen_layout_portrait">Retrato</string>
|
||||||
|
<string name="screen_layout_auto">Auto</string>
|
||||||
|
|
||||||
<!-- Aspect Ratios -->
|
<!-- Aspect Ratios -->
|
||||||
<string name="ratio_default">Predeterminado (16:9)</string>
|
<string name="ratio_default">Predeterminado (16:9)</string>
|
||||||
<string name="ratio_force_four_three">Forzar 4:3</string>
|
<string name="ratio_force_four_three">Forzar 4:3</string>
|
||||||
|
@ -298,7 +380,7 @@
|
||||||
<string name="building_shaders">Construyendo shaders</string>
|
<string name="building_shaders">Construyendo shaders</string>
|
||||||
|
|
||||||
<!-- Theme options -->
|
<!-- Theme options -->
|
||||||
<string name="change_app_theme">Cambiar Tema</string>
|
<string name="change_app_theme">Cambiar tema</string>
|
||||||
<string name="theme_default">Predeterminado</string>
|
<string name="theme_default">Predeterminado</string>
|
||||||
<string name="theme_material_you">Material You</string>
|
<string name="theme_material_you">Material You</string>
|
||||||
|
|
||||||
|
@ -308,8 +390,22 @@
|
||||||
<string name="theme_mode_light">Claro</string>
|
<string name="theme_mode_light">Claro</string>
|
||||||
<string name="theme_mode_dark">Oscuro</string>
|
<string name="theme_mode_dark">Oscuro</string>
|
||||||
|
|
||||||
|
<!-- Audio output engines -->
|
||||||
|
<string name="cubeb">cubeb</string>
|
||||||
|
|
||||||
<!-- Black backgrounds theme -->
|
<!-- Black backgrounds theme -->
|
||||||
<string name="use_black_backgrounds">Usar Fondos Negros</string>
|
<string name="use_black_backgrounds">Fondos oscuros</string>
|
||||||
<string name="use_black_backgrounds_description">Cuando utilice el modo oscuro, aplique fondos negros.</string>
|
<string name="use_black_backgrounds_description">Cuando utilice el modo oscuro, aplique fondos negros.</string>
|
||||||
|
|
||||||
|
<!-- Picture-In-Picture -->
|
||||||
|
<string name="picture_in_picture">Picture in Picture</string>
|
||||||
|
<string name="picture_in_picture_description">Minimizar ventana cuando esté en segundo plano</string>
|
||||||
|
<string name="pause">Pausar</string>
|
||||||
|
<string name="play">Jugar</string>
|
||||||
|
<string name="mute">Mutear</string>
|
||||||
|
<string name="unmute">Desmutear</string>
|
||||||
|
|
||||||
|
<!-- Licenses screen strings -->
|
||||||
|
<string name="licenses">Licencias</string>
|
||||||
|
<string name="license_fidelityfx_fsr_description">Upscaling de alta calidad de AMD</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue