Compare commits
293 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 14cbcc2438 | |||
| 0a73fb5229 | |||
| 254250a83d | |||
| 83c727794e | |||
| a6c610cf26 | |||
| 0dafab4053 | |||
| 40b2fd0e6b | |||
| 610e9eb516 | |||
| d835cab32d | |||
| 46c2a81f4a | |||
| 1ebdef1a02 | |||
| bd80d603e2 | |||
| 76bb5fc18b | |||
| b1821cb60e | |||
| b1cc417c55 | |||
| 70620c245c | |||
| 8389a98648 | |||
| 7fe40a37ef | |||
| e05c74108f | |||
| cd7414814a | |||
| dfe1f39a4b | |||
| 3f1f20185c | |||
| 1845d5b222 | |||
| 1240268048 | |||
| a134ad3fbd | |||
| da30efbc55 | |||
| 2dbca791f6 | |||
| 74248bd35a | |||
| e715925d52 | |||
| 852b8e176f | |||
| b2b07abbc8 | |||
| ce2f2187bd | |||
| 8c077fc4cd | |||
| b88ca5b635 | |||
| 4755ec7a59 | |||
| e20875d8fc | |||
| 58bff28b04 | |||
| 570cd64c03 | |||
| b0a607539a | |||
| 64163f2d2a | |||
| 631ad933b2 | |||
| 6985aaf614 | |||
| d1466b0e9d | |||
| a02e8a5679 | |||
| e98280bee9 | |||
| 1d0a3e83fa | |||
| 4343874a69 | |||
| 11d5c0f96a | |||
| ca42578d4e | |||
| b7087a16ba | |||
| 1bdedc17ad | |||
| 32e63b5fa2 | |||
| 2e89bb890a | |||
| 842acf2c86 | |||
| 2d4c460011 | |||
| c42c67ab85 | |||
| 5bce1993e1 | |||
| 8c79a3a8de | |||
| ebb3cda782 | |||
| daf972b517 | |||
| cd25e61afa | |||
| 4a7aa1618a | |||
| 1aae75512b | |||
| 825b899bf8 | |||
| 73c16c3d45 | |||
| 124c97a88a | |||
| 02f9c5ffd2 | |||
| 042a10cf71 | |||
| d6a889828f | |||
| d06eb3f52f | |||
| 21c77d5dce | |||
| a80e0f10ba | |||
| ccb518dc05 | |||
| bb768ad570 | |||
| c028d925bc | |||
| 3557ff28b7 | |||
| 108bb3d28b | |||
| 5b12a7725d | |||
| 15d575aa31 | |||
| 47fe86be7b | |||
| 3db45f3c46 | |||
| 4481391474 | |||
| dee102cf92 | |||
| ad2f40b0e7 | |||
| d10080b757 | |||
| ce15cf7cd3 | |||
| 6b87b0052a | |||
| 9630da580d | |||
| 12fdd88a58 | |||
| 646aea7fbf | |||
| 186c0b0cc7 | |||
| ee1ffbaf2e | |||
| c931de0570 | |||
| 33f1fb1cf4 | |||
| aabc470314 | |||
| d82a6a273d | |||
| 4bb853d52a | |||
| 43ebdb1ffc | |||
| e310f0b151 | |||
| 9b915c8659 | |||
| 35ab33de6a | |||
| 5615ea9ced | |||
| d273fc4ad6 | |||
| e3e880e879 | |||
| 6b8115f27a | |||
| a24e7e8143 | |||
| 88b9393b44 | |||
| 2081d659d2 | |||
| 9eacaf2444 | |||
| c9eb764d2a | |||
| 72ced6b947 | |||
| ffae2350ca | |||
| 646542a397 | |||
| 1ae76d44c1 | |||
| 24d07ab28c | |||
| 651a999017 | |||
| 5c0e12fb0e | |||
| 712c505cd1 | |||
| 051522b54e | |||
| a1fdbef129 | |||
| ecd5c751f8 | |||
| 69678d02b6 | |||
| 8d031532d8 | |||
| c8e4818b01 | |||
| 2bac9cec32 | |||
| 6190fcaaef | |||
| 3272e1fcb5 | |||
| 8faeffdc7e | |||
| ddac8c8eb5 | |||
| c062931c9b | |||
| e4122dae1d | |||
| b75e81af5e | |||
| 2ed1328c93 | |||
| c70b857c4f | |||
| 23566a1f7d | |||
| 529b069499 | |||
| 9a07bd0570 | |||
| 05f6942bef | |||
| 70c1e9abed | |||
| 69e47bd2c0 | |||
| cdf9b556b2 | |||
| 7f5de6bcd6 | |||
| c682306788 | |||
| 9d2341eaea | |||
| d720a7b4b4 | |||
| 464212393e | |||
| ea209e6dab | |||
| b5f9f8b743 | |||
| a8fc994c0b | |||
| 2991bd18ef | |||
| 281d7a468e | |||
| 12f89745be | |||
| 7de5eb6884 | |||
| ac181b756f | |||
| 4a833e7206 | |||
| 06a08de68a | |||
| f8712e50e6 | |||
| fc63de39dd | |||
| bf25058dbd | |||
| 75104b6103 | |||
| 0d950195e9 | |||
| 04e88ab82c | |||
| f957c36238 | |||
| ee67853636 | |||
| 0ff84ef312 | |||
| 00e2128fab | |||
| f25582833a | |||
| 7758f70833 | |||
| 5279e76534 | |||
| 270232e8d6 | |||
| d2bef2731c | |||
| b45c78a051 | |||
| 40251c2115 | |||
| 83cdeed3c4 | |||
| f77c91431f | |||
| 213f7b810d | |||
| a11eae425a | |||
| c610b61126 | |||
| 963f9981ce | |||
| 89dd600790 | |||
| eb57e11f42 | |||
| 45eb9cfcee | |||
| 0a687b82d4 | |||
| 80d6172084 | |||
| d8b2971a2e | |||
| 12157214b6 | |||
| 0574d7d2c9 | |||
| d64f7dfe5c | |||
| 2d27359074 | |||
| 978ba3ed6f | |||
| f1e9e846f1 | |||
| 097ccf830d | |||
| fecf763a51 | |||
| a12eb5fef6 | |||
| 4014b45cb6 | |||
| 2082ba7ec7 | |||
| bfc720152a | |||
| b6238d6df7 | |||
| f94bae10f2 | |||
| d19303883e | |||
| 5ee81a4932 | |||
| 4f29128e50 | |||
| f76dc401c3 | |||
| 732b7eb560 | |||
| 93eecca894 | |||
| d5aa10d572 | |||
| 308a995275 | |||
| f8145152c7 | |||
| c9c136bea7 | |||
| 6f9d025ad2 | |||
| ab129cf314 | |||
| 72b3f3a8a5 | |||
| 5fb3ae487c | |||
| 86e02aceba | |||
| 50ec0892c6 | |||
| f4e7fc91ba | |||
| 45c9f9bbb3 | |||
| 8e373eb714 | |||
| 75ebfaa090 | |||
| e3035ae8f2 | |||
| bcd22d9f8b | |||
| 4e7c036c7e | |||
| 19e2dba35a | |||
| 0634b4a278 | |||
| ee428deb1e | |||
| 07bc77c7e7 | |||
| 72973fe582 | |||
| c263b6af6f | |||
| e46576b4c3 | |||
| 89bcb73d47 | |||
| 7d81a724ef | |||
| 634686d59b | |||
| d0af14632e | |||
| c87986b276 | |||
| b600b90d53 | |||
| 2b979024cb | |||
| 5f676a6a55 | |||
| 2ab5b37137 | |||
| f6547fac8c | |||
| 9c685c1449 | |||
| aaf1a597ef | |||
| 850fc372b7 | |||
| bad9d8043b | |||
| 8e8e66f880 | |||
| fec5ac2298 | |||
| 19494bc7ac | |||
| 28a78d76fe | |||
| 6b3f8e1b62 | |||
| aacc40254c | |||
| efd26c3e4d | |||
| a8093c2a3c | |||
| 0f8b35c4cd | |||
| 866881d0e3 | |||
| a56b8d3de8 | |||
| e544cb3cf6 | |||
| ca9f2d43be | |||
| e10f55d9db | |||
| 71e035f83b | |||
| 16f2564478 | |||
| 75fda70db2 | |||
| b9e052b3a7 | |||
| 69aff83ef4 | |||
| e07e269bd7 | |||
| 08232ce642 | |||
| d536a66010 | |||
| 8907523ee4 | |||
| 9b1f6801a5 | |||
| ff03ef657a | |||
| 5acddfde16 | |||
| 913a74dbd3 | |||
| cbb92e75d3 | |||
| bd7d0e0466 | |||
| cce77b8d11 | |||
| c2f4449b1c | |||
| 48ba1f3f24 | |||
| d59fcf01bf | |||
| b8456394f1 | |||
| a467dd1ba6 | |||
| c156f4760f | |||
| 13f11ebf49 | |||
| 6065e9aa09 | |||
| 8ed0ed5828 | |||
| 33067af283 | |||
| d0a054270e | |||
| 2a3507c2b9 | |||
| f71f43561d | |||
| ecbfad4193 | |||
| d76b2b5d26 | |||
| cd9527072d | |||
| ffdaf7369a | |||
| 5113f503d1 | |||
| a5f1c2bcb0 | |||
| 2e432c9d17 |
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
case "$1" in
|
||||
@@ -104,8 +104,7 @@ cmake .. -G Ninja \
|
||||
-DYUZU_USE_QT_MULTIMEDIA=$MULTIMEDIA \
|
||||
-DYUZU_USE_QT_WEB_ENGINE=$WEBENGINE \
|
||||
-DYUZU_USE_FASTER_LD=ON \
|
||||
-DYUZU_ENABLE_LTO=ON \
|
||||
-DDYNARMIC_ENABLE_LTO=ON \
|
||||
-DENABLE_LTO=ON \
|
||||
"${EXTRA_CMAKE_FLAGS[@]}"
|
||||
|
||||
ninja -j${NPROC}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
if [ "$COMPILER" == "clang" ]
|
||||
@@ -32,9 +32,8 @@ cmake .. -G Ninja \
|
||||
-DYUZU_ROOM_STANDALONE=OFF \
|
||||
-DYUZU_USE_QT_MULTIMEDIA=${USE_MULTIMEDIA:-false} \
|
||||
-DYUZU_USE_QT_WEB_ENGINE=${USE_WEBENGINE:-false} \
|
||||
-DYUZU_ENABLE_LTO=ON \
|
||||
-DENABLE_LTO=ON \
|
||||
-DCMAKE_EXE_LINKER_FLAGS=" /LTCG" \
|
||||
-DDYNARMIC_ENABLE_LTO=ON \
|
||||
-DYUZU_USE_BUNDLED_QT=${BUNDLE_QT:-false} \
|
||||
-DUSE_CCACHE=${CCACHE:-false} \
|
||||
-DENABLE_UPDATE_CHECKER=${DEVEL:-true} \
|
||||
|
||||
@@ -63,3 +63,4 @@ artifacts
|
||||
*.AppImage*
|
||||
/install*
|
||||
vulkansdk*.exe
|
||||
*.tar.zst
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/libs/context/CMakeLists.txt 2025-09-08 00:42:31.303651800 -0400
|
||||
+++ b/libs/context/CMakeLists.txt 2025-09-08 00:42:40.592184300 -0400
|
||||
@@ -146,7 +146,7 @@
|
||||
set(ASM_LANGUAGE ASM)
|
||||
endif()
|
||||
elseif(BOOST_CONTEXT_ASSEMBLER STREQUAL armasm)
|
||||
- set(ASM_LANGUAGE ASM_ARMASM)
|
||||
+ set(ASM_LANGUAGE ASM_MARMASM)
|
||||
else()
|
||||
set(ASM_LANGUAGE ASM_MASM)
|
||||
endif()
|
||||
@@ -1,14 +0,0 @@
|
||||
diff --git a/libs/context/CMakeLists.txt b/libs/context/CMakeLists.txt
|
||||
index 8210f65..0e59dd7 100644
|
||||
--- a/libs/context/CMakeLists.txt
|
||||
+++ b/libs/context/CMakeLists.txt
|
||||
@@ -186,7 +186,8 @@ if(BOOST_CONTEXT_IMPLEMENTATION STREQUAL "fcontext")
|
||||
set_property(SOURCE ${ASM_SOURCES} APPEND PROPERTY COMPILE_OPTIONS "/safeseh")
|
||||
endif()
|
||||
|
||||
- else() # masm
|
||||
+ # armasm doesn't support most of these options
|
||||
+ elseif(NOT BOOST_CONTEXT_ASSEMBLER STREQUAL armasm) # masm
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set_property(SOURCE ${ASM_SOURCES} APPEND PROPERTY COMPILE_OPTIONS "-x" "assembler-with-cpp")
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
@@ -1,52 +1,62 @@
|
||||
From e1a946ffb79022d38351a0623f819a5419965c3e Mon Sep 17 00:00:00 2001
|
||||
From 436fc1978c78edd085d99b33275b24be0ac96aa0 Mon Sep 17 00:00:00 2001
|
||||
From: crueter <crueter@eden-emu.dev>
|
||||
Date: Fri, 24 Oct 2025 23:41:09 -0700
|
||||
Subject: [PATCH] [build] Fix MinGW missing GetAddrInfoExCancel definition
|
||||
Date: Sun, 1 Feb 2026 16:21:10 -0500
|
||||
Subject: [PATCH] Fix build on MinGW
|
||||
|
||||
MinGW does not define GetAddrInfoExCancel in its wstcpi whatever header,
|
||||
so to get around this we can just load it with GetProcAddress et al.
|
||||
MinGW doesn't define GetAddrInfoExCancel.
|
||||
|
||||
Signed-off-by: crueter <crueter@eden-emu.dev>
|
||||
---
|
||||
httplib.h | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
httplib.h | 18 ++++++++++++++++--
|
||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/httplib.h b/httplib.h
|
||||
index e15ba44..90a76dc 100644
|
||||
index ec8d2a2..5f9a510 100644
|
||||
--- a/httplib.h
|
||||
+++ b/httplib.h
|
||||
@@ -203,11 +203,13 @@
|
||||
@@ -203,14 +203,17 @@
|
||||
#error Sorry, Visual Studio versions prior to 2015 are not supported
|
||||
#endif
|
||||
|
||||
-#pragma comment(lib, "ws2_32.lib")
|
||||
-
|
||||
#ifndef _SSIZE_T_DEFINED
|
||||
using ssize_t = __int64;
|
||||
#define _SSIZE_T_DEFINED
|
||||
#endif
|
||||
#endif // _MSC_VER
|
||||
|
||||
+#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
+#pragma comment(lib, "ws2_32.lib")
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(m) (((m) & S_IFREG) == S_IFREG)
|
||||
#endif // S_ISREG
|
||||
@@ -3557,7 +3559,15 @@ inline int getaddrinfo_with_timeout(const char *node, const char *service,
|
||||
@@ -4528,7 +4531,17 @@ inline int getaddrinfo_with_timeout(const char *node, const char *service,
|
||||
auto wait_result =
|
||||
::WaitForSingleObject(event, static_cast<DWORD>(timeout_sec * 1000));
|
||||
if (wait_result == WAIT_TIMEOUT) {
|
||||
+#ifdef __MINGW32__
|
||||
+ typedef INT (WSAAPI *PFN_GETADDRINFOEXCANCEL)(HANDLE *CancelHandle);
|
||||
+ auto wsdll = LoadLibraryW((wchar_t*) "ws2_32.lib");
|
||||
+ PFN_GETADDRINFOEXCANCEL GetAddrInfoExCancel = (PFN_GETADDRINFOEXCANCEL) GetProcAddress(wsdll, "GetAddrInfoExCancel");
|
||||
+ typedef INT(WSAAPI * PFN_GETADDRINFOEXCANCEL)(HANDLE * CancelHandle);
|
||||
+ auto wsdll = LoadLibraryW((wchar_t *)"ws2_32.lib");
|
||||
+ PFN_GETADDRINFOEXCANCEL GetAddrInfoExCancel =
|
||||
+ (PFN_GETADDRINFOEXCANCEL)GetProcAddress(wsdll, "GetAddrInfoExCancel");
|
||||
+
|
||||
+ if (cancel_handle) { GetAddrInfoExCancel(&cancel_handle); }
|
||||
+#else
|
||||
if (cancel_handle) { ::GetAddrInfoExCancel(&cancel_handle); }
|
||||
+#endif
|
||||
+
|
||||
::CloseHandle(event);
|
||||
return EAI_AGAIN;
|
||||
}
|
||||
@@ -13952,3 +13965,4 @@ inline SSL_CTX *Client::ssl_context() const {
|
||||
} // namespace httplib
|
||||
|
||||
#endif // CPPHTTPLIB_HTTPLIB_H
|
||||
+
|
||||
--
|
||||
2.51.0
|
||||
2.51.2
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
diff --git a/library/aesni.h b/library/aesni.h
|
||||
index 754c984c79..59e27afd3e 100644
|
||||
--- a/library/aesni.h
|
||||
+++ b/library/aesni.h
|
||||
@@ -35,7 +35,7 @@
|
||||
/* GCC-like compilers: currently, we only support intrinsics if the requisite
|
||||
* target flag is enabled when building the library (e.g. `gcc -mpclmul -msse2`
|
||||
* or `clang -maes -mpclmul`). */
|
||||
-#if (defined(__GNUC__) || defined(__clang__)) && defined(__AES__) && defined(__PCLMUL__)
|
||||
+#if defined(__GNUC__) || defined(__clang__)
|
||||
#define MBEDTLS_AESNI_HAVE_INTRINSICS
|
||||
#endif
|
||||
/* For 32-bit, we only support intrinsics */
|
||||
diff --git a/library/aesni.c b/library/aesni.c
|
||||
index 2857068..3e104ab 100644
|
||||
--- a/library/aesni.c
|
||||
+++ b/library/aesni.c
|
||||
@@ -31,16 +31,14 @@
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
-#if defined(MBEDTLS_ARCH_IS_X86)
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC)
|
||||
#pragma GCC push_options
|
||||
#pragma GCC target ("pclmul,sse2,aes")
|
||||
#define MBEDTLS_POP_TARGET_PRAGMA
|
||||
-#elif defined(__clang__) && (__clang_major__ >= 5)
|
||||
+#elif defined(__clang__)
|
||||
#pragma clang attribute push (__attribute__((target("pclmul,sse2,aes"))), apply_to=function)
|
||||
#define MBEDTLS_POP_TARGET_PRAGMA
|
||||
#endif
|
||||
-#endif
|
||||
|
||||
#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
|
||||
/*
|
||||
@@ -1,20 +0,0 @@
|
||||
diff --git a/library/common.h b/library/common.h
|
||||
index 50f2a29..c60d9dc 100644
|
||||
--- a/library/common.h
|
||||
+++ b/library/common.h
|
||||
@@ -19,11 +19,11 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
-#if defined(__ARM_NEON)
|
||||
-#include <arm_neon.h>
|
||||
+#if defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
+#include <arm64_neon.h>
|
||||
#define MBEDTLS_HAVE_NEON_INTRINSICS
|
||||
-#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
-#include <arm64_neon.h>
|
||||
+#elif (defined(__ANDROID__) && defined(__ARM_FP)) || defined(__ARM_NEON)
|
||||
+#include <arm_neon.h>
|
||||
#define MBEDTLS_HAVE_NEON_INTRINSICS
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
From b3622608433c183ba868a1dc8dd9cf285eb3b916 Mon Sep 17 00:00:00 2001
|
||||
From: Dario Petrillo <dario.pk1@gmail.com>
|
||||
Date: Thu, 27 Nov 2025 23:12:38 +0100
|
||||
Subject: [PATCH] avoid extra memset when clearing an empty table
|
||||
|
||||
---
|
||||
include/ankerl/unordered_dense.h | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/ankerl/unordered_dense.h b/include/ankerl/unordered_dense.h
|
||||
index 0835342..4938212 100644
|
||||
--- a/include/ankerl/unordered_dense.h
|
||||
+++ b/include/ankerl/unordered_dense.h
|
||||
@@ -1490,8 +1490,10 @@ class table : public std::conditional_t<is_map_v<T>, base_table_type_map<T>, bas
|
||||
// modifiers //////////////////////////////////////////////////////////////
|
||||
|
||||
void clear() {
|
||||
- m_values.clear();
|
||||
- clear_buckets();
|
||||
+ if (!empty()) {
|
||||
+ m_values.clear();
|
||||
+ clear_buckets();
|
||||
+ }
|
||||
}
|
||||
|
||||
auto insert(value_type const& value) -> std::pair<iterator, bool> {
|
||||
@@ -32,8 +32,8 @@ if (PLATFORM_OPENBSD)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R6/include -D_LIBCPP_PSTL_BACKEND_SERIAL=1")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R6/lib")
|
||||
elseif (PLATFORM_NETBSD)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_SYSROOT}/usr/X11R7/include -I${CMAKE_SYSROOT}/usr/pkg/include/c++/v1")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/X11R7/lib")
|
||||
endif()
|
||||
|
||||
@@ -49,35 +49,28 @@ if (YUZU_STATIC_ROOM)
|
||||
|
||||
# disable e v e r y t h i n g
|
||||
set(ENABLE_QT OFF)
|
||||
set(ENABLE_SDL2 OFF)
|
||||
set(YUZU_CMD OFF)
|
||||
set(ENABLE_CUBEB OFF)
|
||||
set(ENABLE_UPDATE_CHECKER OFF)
|
||||
set(USE_DISCORD_PRESENCE OFF)
|
||||
set(BUILD_TESTING OFF)
|
||||
set(ENABLE_OPENSSL OFF)
|
||||
set(ENABLE_WEB_SERVICE OFF)
|
||||
set(ENABLE_LIBUSB OFF)
|
||||
|
||||
# allow static libs for boost and mbedtls though
|
||||
# allow static libs for boost though
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||
set(MBEDTLS_LIB_SUFFIX "_static")
|
||||
set(YUZU_USE_CPM ON)
|
||||
set(OPENSSL_USE_STATIC_LIBS ON)
|
||||
|
||||
set(zstd_FORCE_BUNDLED ON)
|
||||
set(fmt_FORCE_BUNDLED ON)
|
||||
endif()
|
||||
|
||||
# common network mbedtls
|
||||
# common: xbyak? booost fmt lz4 zstd
|
||||
# network: enet boost
|
||||
|
||||
# qt stuff
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
|
||||
option(ENABLE_UPDATE_CHECKER "Enable update checker (for Qt and Android)" OFF)
|
||||
option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
|
||||
cmake_dependent_option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF "NOT YUZU_USE_BUNDLED_QT" OFF)
|
||||
cmake_dependent_option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF "NOT YUZU_USE_BUNDLED_QT" OFF)
|
||||
set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundled Qt libraries")
|
||||
cmake_dependent_option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF)
|
||||
@@ -130,12 +123,7 @@ if (YUZU_STATIC_BUILD)
|
||||
set(YUZU_USE_BUNDLED_OPENSSL ON)
|
||||
|
||||
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
|
||||
|
||||
## some libraries define a Library::Name_static alternative ##
|
||||
set(MBEDTLS_LIB_SUFFIX _static)
|
||||
elseif(APPLE)
|
||||
set(YUZU_USE_CPM ON)
|
||||
|
||||
set(YUZU_USE_BUNDLED_FFMPEG ON)
|
||||
set(YUZU_USE_BUNDLED_SDL2 ON)
|
||||
set(YUZU_USE_BUNDLED_OPENSSL ON)
|
||||
@@ -145,7 +133,6 @@ if (YUZU_STATIC_BUILD)
|
||||
set(SPIRV-Tools_FORCE_BUNDLED ON)
|
||||
set(SPIRV-Headers_FORCE_BUNDLED ON)
|
||||
set(zstd_FORCE_BUNDLED ON)
|
||||
set(MbedTLS_FORCE_BUNDLED ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -178,16 +165,14 @@ endif()
|
||||
|
||||
# Disable Warnings as Errors for MSVC
|
||||
if (MSVC AND NOT CXX_CLANG)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX-")
|
||||
# This was dripping into spirv, being overriden, and causing cl flag override warning
|
||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX-")
|
||||
set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} /W3 /WX-")
|
||||
endif()
|
||||
|
||||
# Set bundled sdl2/qt as dependent options.
|
||||
# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion
|
||||
cmake_dependent_option(ENABLE_SDL2 "Enable the SDL2 frontend" ON "NOT ANDROID" OFF)
|
||||
|
||||
# TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system
|
||||
cmake_dependent_option(YUZU_USE_EXTERNAL_SDL2 "Build SDL2 from external source" OFF "ENABLE_SDL2;NOT MSVC" OFF)
|
||||
cmake_dependent_option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "ENABLE_SDL2" OFF)
|
||||
cmake_dependent_option(YUZU_USE_EXTERNAL_SDL2 "Build SDL2 from external source" OFF "NOT MSVC;NOT ANDROID" OFF)
|
||||
cmake_dependent_option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "NOT ANDROID" OFF)
|
||||
|
||||
option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
|
||||
|
||||
@@ -196,8 +181,6 @@ if (MSVC OR ANDROID)
|
||||
set(EXT_DEFAULT ON)
|
||||
endif()
|
||||
|
||||
option(YUZU_USE_CPM "Use CPM to fetch system dependencies (fmt, boost, etc) if needed. Externals will still be fetched." ${EXT_DEFAULT})
|
||||
|
||||
# ffmpeg
|
||||
option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT})
|
||||
cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from external source" "${PLATFORM_SUN}" "NOT WIN32 AND NOT ANDROID" OFF)
|
||||
@@ -232,7 +215,7 @@ option(NIGHTLY_BUILD "Use Nightly qualifiers in the update checker and build met
|
||||
cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF)
|
||||
cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF)
|
||||
|
||||
cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "ENABLE_SDL2;NOT ANDROID" OFF)
|
||||
cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "NOT ANDROID" OFF)
|
||||
|
||||
cmake_dependent_option(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR PLATFORM_LINUX" OFF)
|
||||
|
||||
@@ -243,29 +226,12 @@ cmake_dependent_option(YUZU_USE_BUNDLED_MOLTENVK "Download bundled MoltenVK lib"
|
||||
|
||||
option(YUZU_DISABLE_LLVM "Disable LLVM (useful for CI)" OFF)
|
||||
|
||||
set(DEFAULT_ENABLE_OPENSSL ON)
|
||||
if (ANDROID OR WIN32 OR APPLE OR PLATFORM_SUN)
|
||||
# - Windows defaults to the Schannel backend.
|
||||
# - macOS defaults to the SecureTransport backend.
|
||||
# - Android currently has no SSL backend as the NDK doesn't include any SSL
|
||||
# library; a proper 'native' backend would have to go through Java.
|
||||
# But you can force builds for those platforms to use OpenSSL if you have
|
||||
# your own copy of it.
|
||||
set(DEFAULT_ENABLE_OPENSSL OFF)
|
||||
endif()
|
||||
|
||||
if (ENABLE_WEB_SERVICE OR USE_DISCORD_PRESENCE)
|
||||
set(DEFAULT_ENABLE_OPENSSL ON)
|
||||
endif()
|
||||
|
||||
option(ENABLE_OPENSSL "Enable OpenSSL backend for ISslConnection" ${DEFAULT_ENABLE_OPENSSL})
|
||||
|
||||
set(DEFAULT_YUZU_USE_BUNDLED_OPENSSL OFF)
|
||||
if (EXT_DEFAULT OR PLATFORM_SUN)
|
||||
if (EXT_DEFAULT OR PLATFORM_SUN OR PLATFORM_OPENBSD)
|
||||
set(DEFAULT_YUZU_USE_BUNDLED_OPENSSL ON)
|
||||
endif()
|
||||
|
||||
cmake_dependent_option(YUZU_USE_BUNDLED_OPENSSL "Download bundled OpenSSL build" ${DEFAULT_YUZU_USE_BUNDLED_OPENSSL} "ENABLE_OPENSSL" OFF)
|
||||
option(YUZU_USE_BUNDLED_OPENSSL "Download bundled OpenSSL build" ${DEFAULT_YUZU_USE_BUNDLED_OPENSSL})
|
||||
|
||||
if (ANDROID AND YUZU_DOWNLOAD_ANDROID_VVL)
|
||||
AddJsonPackage(vulkan-validation-layers)
|
||||
@@ -393,123 +359,94 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
# openssl funniness
|
||||
if (ENABLE_OPENSSL)
|
||||
if (YUZU_USE_BUNDLED_OPENSSL)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
AddJsonPackage(openssl)
|
||||
if (OpenSSL_ADDED)
|
||||
add_compile_definitions(YUZU_BUNDLED_OPENSSL)
|
||||
endif()
|
||||
endif()
|
||||
find_package(RenderDoc MODULE)
|
||||
|
||||
find_package(OpenSSL 1.1.1 REQUIRED)
|
||||
# openssl funniness
|
||||
if (YUZU_USE_BUNDLED_OPENSSL)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
AddJsonPackage(openssl)
|
||||
if (OpenSSL_ADDED)
|
||||
add_compile_definitions(YUZU_BUNDLED_OPENSSL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (YUZU_USE_CPM)
|
||||
message(STATUS "Fetching needed dependencies with CPM")
|
||||
find_package(OpenSSL 3 REQUIRED)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(BUILD_TESTING OFF)
|
||||
set(ENABLE_TESTING OFF)
|
||||
message(STATUS "Fetching needed dependencies with CPM")
|
||||
|
||||
# TODO(crueter): renderdoc?
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(BUILD_TESTING OFF)
|
||||
set(ENABLE_TESTING OFF)
|
||||
|
||||
# boost
|
||||
set(BOOST_INCLUDE_LIBRARIES algorithm icl pool container heap asio headers process filesystem crc variant)
|
||||
# boost
|
||||
set(BOOST_INCLUDE_LIBRARIES algorithm icl pool container heap asio headers process filesystem crc variant)
|
||||
|
||||
AddJsonPackage(boost)
|
||||
AddJsonPackage(boost)
|
||||
|
||||
# really annoying thing where boost::headers doesn't work with cpm
|
||||
# TODO(crueter) investigate
|
||||
set(BOOST_NO_HEADERS ${Boost_ADDED})
|
||||
# really annoying thing where boost::headers doesn't work with cpm
|
||||
# TODO(crueter) investigate
|
||||
set(BOOST_NO_HEADERS ${Boost_ADDED})
|
||||
|
||||
if (Boost_ADDED)
|
||||
if (MSVC OR ANDROID)
|
||||
add_compile_definitions(YUZU_BOOST_v1)
|
||||
if (Boost_ADDED)
|
||||
if (MSVC OR ANDROID)
|
||||
add_compile_definitions(YUZU_BOOST_v1)
|
||||
endif()
|
||||
|
||||
if (NOT MSVC OR CXX_CLANG)
|
||||
# boost sucks
|
||||
if (PLATFORM_SUN)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthreads")
|
||||
endif()
|
||||
|
||||
if (NOT MSVC OR CXX_CLANG)
|
||||
# boost sucks
|
||||
if (PLATFORM_SUN)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthreads")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthreads")
|
||||
endif()
|
||||
target_compile_options(boost_heap INTERFACE -Wno-shadow)
|
||||
target_compile_options(boost_icl INTERFACE -Wno-shadow)
|
||||
target_compile_options(boost_asio INTERFACE -Wno-conversion -Wno-implicit-fallthrough)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_options(boost_heap INTERFACE -Wno-shadow)
|
||||
target_compile_options(boost_icl INTERFACE -Wno-shadow)
|
||||
target_compile_options(boost_asio INTERFACE -Wno-conversion -Wno-implicit-fallthrough)
|
||||
# fmt
|
||||
AddJsonPackage(fmt)
|
||||
|
||||
# lz4
|
||||
AddJsonPackage(lz4)
|
||||
|
||||
if (lz4_ADDED)
|
||||
add_library(lz4::lz4 ALIAS lz4_static)
|
||||
endif()
|
||||
|
||||
# zstd
|
||||
AddJsonPackage(zstd)
|
||||
|
||||
if (zstd_ADDED)
|
||||
add_library(zstd::zstd ALIAS libzstd_static)
|
||||
add_library(zstd::libzstd ALIAS libzstd_static)
|
||||
endif()
|
||||
|
||||
if (NOT YUZU_STATIC_ROOM)
|
||||
# nlohmann
|
||||
AddJsonPackage(nlohmann)
|
||||
|
||||
# zlib
|
||||
AddJsonPackage(zlib)
|
||||
|
||||
if (ZLIB_ADDED)
|
||||
add_library(ZLIB::ZLIB ALIAS zlibstatic)
|
||||
endif()
|
||||
|
||||
# Opus
|
||||
AddJsonPackage(opus)
|
||||
|
||||
if (Opus_ADDED)
|
||||
if (MSVC AND CXX_CLANG)
|
||||
target_compile_options(opus PRIVATE
|
||||
-Wno-implicit-function-declaration
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# fmt
|
||||
AddJsonPackage(fmt)
|
||||
|
||||
# lz4
|
||||
AddJsonPackage(lz4)
|
||||
|
||||
if (lz4_ADDED)
|
||||
add_library(lz4::lz4 ALIAS lz4_static)
|
||||
endif()
|
||||
|
||||
# zstd
|
||||
AddJsonPackage(zstd)
|
||||
|
||||
if (zstd_ADDED)
|
||||
add_library(zstd::zstd ALIAS libzstd_static)
|
||||
add_library(zstd::libzstd ALIAS libzstd_static)
|
||||
endif()
|
||||
|
||||
if (NOT YUZU_STATIC_ROOM)
|
||||
# nlohmann
|
||||
AddJsonPackage(nlohmann)
|
||||
|
||||
# zlib
|
||||
AddJsonPackage(zlib)
|
||||
|
||||
if (ZLIB_ADDED)
|
||||
add_library(ZLIB::ZLIB ALIAS zlibstatic)
|
||||
endif()
|
||||
|
||||
# Opus
|
||||
AddJsonPackage(opus)
|
||||
|
||||
if (Opus_ADDED)
|
||||
if (MSVC AND CXX_CLANG)
|
||||
target_compile_options(opus PRIVATE
|
||||
-Wno-implicit-function-declaration
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT TARGET Opus::opus)
|
||||
add_library(Opus::opus ALIAS opus)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# TODO: we can probably just use CPM for this... right?
|
||||
# Enforce the search mode of non-required packages for better and shorter failure messages
|
||||
find_package(fmt 8 REQUIRED)
|
||||
|
||||
if (NOT YUZU_DISABLE_LLVM)
|
||||
find_package(LLVM MODULE COMPONENTS Demangle)
|
||||
endif()
|
||||
|
||||
find_package(nlohmann_json 3.8 REQUIRED)
|
||||
find_package(lz4 REQUIRED)
|
||||
find_package(RenderDoc MODULE)
|
||||
find_package(stb MODULE)
|
||||
|
||||
find_package(Opus 1.3 MODULE REQUIRED)
|
||||
|
||||
find_package(ZLIB 1.2 REQUIRED)
|
||||
find_package(zstd 1.5 REQUIRED MODULE)
|
||||
|
||||
# wow
|
||||
find_package(Boost 1.57.0 CONFIG REQUIRED OPTIONAL_COMPONENTS headers context system fiber filesystem)
|
||||
|
||||
if (ENABLE_OPENSSL)
|
||||
find_package(OpenSSL 1.1.1 REQUIRED)
|
||||
if (NOT TARGET Opus::opus)
|
||||
add_library(Opus::opus ALIAS opus)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -571,8 +508,9 @@ message(STATUS "Platform Libraries: ${PLATFORM_LIBRARIES}")
|
||||
add_subdirectory(externals)
|
||||
|
||||
# pass targets from externals
|
||||
# TODO(crueter): CPMUtil Propagate func?
|
||||
find_package(enet)
|
||||
find_package(MbedTLS)
|
||||
find_package(unordered_dense REQUIRED)
|
||||
|
||||
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
|
||||
find_package(xbyak)
|
||||
@@ -587,6 +525,7 @@ if (NOT YUZU_STATIC_ROOM)
|
||||
find_package(sirit)
|
||||
find_package(gamemode)
|
||||
find_package(mcl)
|
||||
find_package(frozen)
|
||||
|
||||
if (ARCHITECTURE_riscv64)
|
||||
find_package(biscuit)
|
||||
@@ -600,7 +539,7 @@ if (NOT YUZU_STATIC_ROOM)
|
||||
find_package(oaknut)
|
||||
endif()
|
||||
|
||||
if (ENABLE_SDL2)
|
||||
if (NOT ANDROID)
|
||||
find_package(SDL2)
|
||||
endif()
|
||||
|
||||
@@ -636,7 +575,7 @@ if (ENABLE_QT)
|
||||
list(APPEND CMAKE_PREFIX_PATH "${Qt6_DIR}")
|
||||
endif()
|
||||
|
||||
find_package(Qt6 CONFIG REQUIRED COMPONENTS Widgets Concurrent)
|
||||
find_package(Qt6 CONFIG REQUIRED COMPONENTS Widgets Charts Concurrent)
|
||||
|
||||
if (YUZU_USE_QT_MULTIMEDIA)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Multimedia)
|
||||
@@ -675,7 +614,7 @@ if (ENABLE_QT)
|
||||
## Components ##
|
||||
|
||||
# Best practice is to ask for all components at once, so they are from the same version
|
||||
set(YUZU_QT_COMPONENTS Core Widgets Concurrent)
|
||||
set(YUZU_QT_COMPONENTS Core Widgets Charts Concurrent)
|
||||
if (PLATFORM_LINUX)
|
||||
list(APPEND YUZU_QT_COMPONENTS DBus)
|
||||
endif()
|
||||
@@ -693,6 +632,11 @@ if (ENABLE_QT)
|
||||
set(QT_MAJOR_VERSION 6)
|
||||
# Qt6 sets cxx_std_17 and we need to undo that
|
||||
set_target_properties(Qt6::Platform PROPERTIES INTERFACE_COMPILE_FEATURES "")
|
||||
|
||||
## Qt Externals ##
|
||||
|
||||
# QuaZip
|
||||
AddJsonPackage(quazip)
|
||||
endif()
|
||||
|
||||
if (NOT YUZU_STATIC_ROOM AND NOT (YUZU_USE_BUNDLED_FFMPEG OR YUZU_USE_EXTERNAL_FFMPEG))
|
||||
|
||||
@@ -41,6 +41,11 @@ function(cpm_utils_message level name message)
|
||||
message(${level} "[CPMUtil] ${name}: ${message}")
|
||||
endfunction()
|
||||
|
||||
# propagate a variable to parent scope
|
||||
macro(Propagate var)
|
||||
set(${var} ${${var}} PARENT_SCOPE)
|
||||
endmacro()
|
||||
|
||||
function(array_to_list array length out)
|
||||
math(EXPR range "${length} - 1")
|
||||
|
||||
@@ -72,6 +77,163 @@ function(get_json_element object out member default)
|
||||
set("${out}" "${outvar}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Determine whether or not a package has a viable system candidate.
|
||||
function(SystemPackageViable JSON_NAME)
|
||||
string(JSON object GET "${CPMFILE_CONTENT}" "${JSON_NAME}")
|
||||
|
||||
parse_object(${object})
|
||||
|
||||
string(REPLACE " " ";" find_args "${find_args}")
|
||||
if (${package}_FORCE_BUNDLED)
|
||||
set(${package}_FOUND OFF)
|
||||
else()
|
||||
find_package(${package} ${version} ${find_args} QUIET NO_POLICY_SCOPE)
|
||||
endif()
|
||||
|
||||
set(${pkg}_VIABLE ${${package}_FOUND} PARENT_SCOPE)
|
||||
set(${pkg}_PACKAGE ${package} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Add several packages such that if one is bundled,
|
||||
# all the rest must also be bundled.
|
||||
function(AddDependentPackages)
|
||||
set(_some_system OFF)
|
||||
set(_some_bundled OFF)
|
||||
|
||||
foreach(pkg ${ARGN})
|
||||
SystemPackageViable(${pkg})
|
||||
|
||||
if (${pkg}_VIABLE)
|
||||
set(_some_system ON)
|
||||
list(APPEND _system_pkgs ${${pkg}_PACKAGE})
|
||||
else()
|
||||
set(_some_bundled ON)
|
||||
list(APPEND _bundled_pkgs ${${pkg}_PACKAGE})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (_some_system AND _some_bundled)
|
||||
foreach(pkg ${ARGN})
|
||||
list(APPEND package_names ${${pkg}_PACKAGE})
|
||||
endforeach()
|
||||
|
||||
string(REPLACE ";" ", " package_names "${package_names}")
|
||||
string(REPLACE ";" ", " bundled_names "${_bundled_pkgs}")
|
||||
foreach(sys ${_system_pkgs})
|
||||
list(APPEND system_names ${sys}_FORCE_BUNDLED)
|
||||
endforeach()
|
||||
|
||||
string(REPLACE ";" ", " system_names "${system_names}")
|
||||
|
||||
message(FATAL_ERROR "Partial dependency installation detected "
|
||||
"for the following packages:\n${package_names}\n"
|
||||
"You can solve this in one of two ways:\n"
|
||||
"1. Install the following packages to your system if available:"
|
||||
"\n\t${bundled_names}\n"
|
||||
"2. Set the following variables to ON:"
|
||||
"\n\t${system_names}\n"
|
||||
"This may also be caused by a version mismatch, "
|
||||
"such as one package being newer than the other.")
|
||||
endif()
|
||||
|
||||
foreach(pkg ${ARGN})
|
||||
AddJsonPackage(${pkg})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# json util
|
||||
macro(parse_object object)
|
||||
get_json_element("${object}" package package ${JSON_NAME})
|
||||
get_json_element("${object}" repo repo "")
|
||||
get_json_element("${object}" ci ci OFF)
|
||||
get_json_element("${object}" version version "")
|
||||
|
||||
if(ci)
|
||||
get_json_element("${object}" name name "${JSON_NAME}")
|
||||
get_json_element("${object}" extension extension "tar.zst")
|
||||
get_json_element("${object}" min_version min_version "")
|
||||
get_json_element("${object}" raw_disabled disabled_platforms "")
|
||||
|
||||
if(raw_disabled)
|
||||
array_to_list("${raw_disabled}"
|
||||
${raw_disabled_LENGTH} disabled_platforms)
|
||||
else()
|
||||
set(disabled_platforms "")
|
||||
endif()
|
||||
else()
|
||||
get_json_element("${object}" hash hash "")
|
||||
get_json_element("${object}" hash_suffix hash_suffix "")
|
||||
get_json_element("${object}" sha sha "")
|
||||
get_json_element("${object}" url url "")
|
||||
get_json_element("${object}" key key "")
|
||||
get_json_element("${object}" tag tag "")
|
||||
get_json_element("${object}" artifact artifact "")
|
||||
get_json_element("${object}" git_version git_version "")
|
||||
get_json_element("${object}" git_host git_host "")
|
||||
get_json_element("${object}" source_subdir source_subdir "")
|
||||
get_json_element("${object}" bundled bundled "unset")
|
||||
get_json_element("${object}" find_args find_args "")
|
||||
get_json_element("${object}" raw_patches patches "")
|
||||
|
||||
# okay here comes the fun part: REPLACEMENTS!
|
||||
# first: tag gets %VERSION% replaced if applicable,
|
||||
# with either git_version (preferred) or version
|
||||
# second: artifact gets %VERSION% and %TAG% replaced
|
||||
# accordingly (same rules for VERSION)
|
||||
|
||||
if(git_version)
|
||||
set(version_replace ${git_version})
|
||||
else()
|
||||
set(version_replace ${version})
|
||||
endif()
|
||||
|
||||
# TODO(crueter): fmt module for cmake
|
||||
if(tag)
|
||||
string(REPLACE "%VERSION%" "${version_replace}" tag ${tag})
|
||||
endif()
|
||||
|
||||
if(artifact)
|
||||
string(REPLACE "%VERSION%" "${version_replace}"
|
||||
artifact ${artifact})
|
||||
string(REPLACE "%TAG%" "${tag}" artifact ${artifact})
|
||||
endif()
|
||||
|
||||
# format patchdir
|
||||
if(raw_patches)
|
||||
math(EXPR range "${raw_patches_LENGTH} - 1")
|
||||
|
||||
foreach(IDX RANGE ${range})
|
||||
string(JSON _patch GET "${raw_patches}" "${IDX}")
|
||||
|
||||
set(full_patch
|
||||
"${PROJECT_SOURCE_DIR}/.patch/${JSON_NAME}/${_patch}")
|
||||
if(NOT EXISTS ${full_patch})
|
||||
cpm_utils_message(FATAL_ERROR ${JSON_NAME}
|
||||
"specifies patch ${full_patch} which does not exist")
|
||||
endif()
|
||||
|
||||
list(APPEND patches "${full_patch}")
|
||||
endforeach()
|
||||
endif()
|
||||
# end format patchdir
|
||||
|
||||
# options
|
||||
get_json_element("${object}" raw_options options "")
|
||||
|
||||
if(raw_options)
|
||||
array_to_list("${raw_options}" ${raw_options_LENGTH} options)
|
||||
endif()
|
||||
|
||||
set(options ${options} ${JSON_OPTIONS})
|
||||
# end options
|
||||
|
||||
# system/bundled
|
||||
if(bundled STREQUAL "unset" AND DEFINED JSON_BUNDLED_PACKAGE)
|
||||
set(bundled ${JSON_BUNDLED_PACKAGE})
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# The preferred usage
|
||||
function(AddJsonPackage)
|
||||
set(oneValueArgs
|
||||
@@ -80,7 +242,8 @@ function(AddJsonPackage)
|
||||
# these are overrides that can be generated at runtime,
|
||||
# so can be defined separately from the json
|
||||
DOWNLOAD_ONLY
|
||||
BUNDLED_PACKAGE)
|
||||
BUNDLED_PACKAGE
|
||||
FORCE_BUNDLED_PACKAGE)
|
||||
|
||||
set(multiValueArgs OPTIONS)
|
||||
|
||||
@@ -111,24 +274,9 @@ function(AddJsonPackage)
|
||||
cpm_utils_message(FATAL_ERROR ${JSON_NAME} "Not found in cpmfile")
|
||||
endif()
|
||||
|
||||
get_json_element("${object}" package package ${JSON_NAME})
|
||||
get_json_element("${object}" repo repo "")
|
||||
get_json_element("${object}" ci ci OFF)
|
||||
get_json_element("${object}" version version "")
|
||||
parse_object(${object})
|
||||
|
||||
if(ci)
|
||||
get_json_element("${object}" name name "${JSON_NAME}")
|
||||
get_json_element("${object}" extension extension "tar.zst")
|
||||
get_json_element("${object}" min_version min_version "")
|
||||
get_json_element("${object}" raw_disabled disabled_platforms "")
|
||||
|
||||
if(raw_disabled)
|
||||
array_to_list("${raw_disabled}"
|
||||
${raw_disabled_LENGTH} disabled_platforms)
|
||||
else()
|
||||
set(disabled_platforms "")
|
||||
endif()
|
||||
|
||||
AddCIPackage(
|
||||
VERSION ${version}
|
||||
NAME ${name}
|
||||
@@ -138,116 +286,38 @@ function(AddJsonPackage)
|
||||
MIN_VERSION ${min_version}
|
||||
DISABLED_PLATFORMS ${disabled_platforms})
|
||||
|
||||
# pass stuff to parent scope
|
||||
set(${package}_ADDED "${${package}_ADDED}"
|
||||
PARENT_SCOPE)
|
||||
set(${package}_SOURCE_DIR "${${package}_SOURCE_DIR}"
|
||||
PARENT_SCOPE)
|
||||
set(${package}_BINARY_DIR "${${package}_BINARY_DIR}"
|
||||
PARENT_SCOPE)
|
||||
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_json_element("${object}" hash hash "")
|
||||
get_json_element("${object}" hash_suffix hash_suffix "")
|
||||
get_json_element("${object}" sha sha "")
|
||||
get_json_element("${object}" url url "")
|
||||
get_json_element("${object}" key key "")
|
||||
get_json_element("${object}" tag tag "")
|
||||
get_json_element("${object}" artifact artifact "")
|
||||
get_json_element("${object}" git_version git_version "")
|
||||
get_json_element("${object}" git_host git_host "")
|
||||
get_json_element("${object}" source_subdir source_subdir "")
|
||||
get_json_element("${object}" bundled bundled "unset")
|
||||
get_json_element("${object}" find_args find_args "")
|
||||
get_json_element("${object}" raw_patches patches "")
|
||||
|
||||
# okay here comes the fun part: REPLACEMENTS!
|
||||
# first: tag gets %VERSION% replaced if applicable,
|
||||
# with either git_version (preferred) or version
|
||||
# second: artifact gets %VERSION% and %TAG% replaced
|
||||
# accordingly (same rules for VERSION)
|
||||
|
||||
if(git_version)
|
||||
set(version_replace ${git_version})
|
||||
else()
|
||||
set(version_replace ${version})
|
||||
if (NOT DEFINED JSON_FORCE_BUNDLED_PACKAGE)
|
||||
set(JSON_FORCE_BUNDLED_PACKAGE OFF)
|
||||
endif()
|
||||
|
||||
AddPackage(
|
||||
NAME "${package}"
|
||||
VERSION "${version}"
|
||||
URL "${url}"
|
||||
HASH "${hash}"
|
||||
HASH_SUFFIX "${hash_suffix}"
|
||||
SHA "${sha}"
|
||||
REPO "${repo}"
|
||||
KEY "${key}"
|
||||
PATCHES "${patches}"
|
||||
OPTIONS "${options}"
|
||||
FIND_PACKAGE_ARGUMENTS "${find_args}"
|
||||
BUNDLED_PACKAGE "${bundled}"
|
||||
FORCE_BUNDLED_PACKAGE "${JSON_FORCE_BUNDLED_PACKAGE}"
|
||||
SOURCE_SUBDIR "${source_subdir}"
|
||||
|
||||
GIT_VERSION ${git_version}
|
||||
GIT_HOST ${git_host}
|
||||
|
||||
ARTIFACT ${artifact}
|
||||
TAG ${tag})
|
||||
endif()
|
||||
|
||||
# TODO(crueter): fmt module for cmake
|
||||
if(tag)
|
||||
string(REPLACE "%VERSION%" "${version_replace}" tag ${tag})
|
||||
endif()
|
||||
|
||||
if(artifact)
|
||||
string(REPLACE "%VERSION%" "${version_replace}" artifact ${artifact})
|
||||
string(REPLACE "%TAG%" "${tag}" artifact ${artifact})
|
||||
endif()
|
||||
|
||||
# format patchdir
|
||||
if(raw_patches)
|
||||
math(EXPR range "${raw_patches_LENGTH} - 1")
|
||||
|
||||
foreach(IDX RANGE ${range})
|
||||
string(JSON _patch GET "${raw_patches}" "${IDX}")
|
||||
|
||||
set(full_patch
|
||||
"${PROJECT_SOURCE_DIR}/.patch/${JSON_NAME}/${_patch}")
|
||||
if(NOT EXISTS ${full_patch})
|
||||
cpm_utils_message(FATAL_ERROR ${JSON_NAME}
|
||||
"specifies patch ${full_patch} which does not exist")
|
||||
endif()
|
||||
|
||||
list(APPEND patches "${full_patch}")
|
||||
endforeach()
|
||||
endif()
|
||||
# end format patchdir
|
||||
|
||||
# options
|
||||
get_json_element("${object}" raw_options options "")
|
||||
|
||||
if(raw_options)
|
||||
array_to_list("${raw_options}" ${raw_options_LENGTH} options)
|
||||
endif()
|
||||
|
||||
set(options ${options} ${JSON_OPTIONS})
|
||||
# end options
|
||||
|
||||
# system/bundled
|
||||
if(bundled STREQUAL "unset" AND DEFINED JSON_BUNDLED_PACKAGE)
|
||||
set(bundled ${JSON_BUNDLED_PACKAGE})
|
||||
endif()
|
||||
|
||||
AddPackage(
|
||||
NAME "${package}"
|
||||
VERSION "${version}"
|
||||
URL "${url}"
|
||||
HASH "${hash}"
|
||||
HASH_SUFFIX "${hash_suffix}"
|
||||
SHA "${sha}"
|
||||
REPO "${repo}"
|
||||
KEY "${key}"
|
||||
PATCHES "${patches}"
|
||||
OPTIONS "${options}"
|
||||
FIND_PACKAGE_ARGUMENTS "${find_args}"
|
||||
BUNDLED_PACKAGE "${bundled}"
|
||||
SOURCE_SUBDIR "${source_subdir}"
|
||||
|
||||
GIT_VERSION ${git_version}
|
||||
GIT_HOST ${git_host}
|
||||
|
||||
ARTIFACT ${artifact}
|
||||
TAG ${tag})
|
||||
|
||||
# pass stuff to parent scope
|
||||
set(${package}_ADDED "${${package}_ADDED}"
|
||||
PARENT_SCOPE)
|
||||
set(${package}_SOURCE_DIR "${${package}_SOURCE_DIR}"
|
||||
PARENT_SCOPE)
|
||||
set(${package}_BINARY_DIR "${${package}_BINARY_DIR}"
|
||||
PARENT_SCOPE)
|
||||
|
||||
Propagate(${package}_ADDED)
|
||||
Propagate(${package}_SOURCE_DIR)
|
||||
Propagate(${package}_BINARY_DIR)
|
||||
endfunction()
|
||||
|
||||
function(AddPackage)
|
||||
@@ -343,7 +413,7 @@ function(AddPackage)
|
||||
|
||||
if(DEFINED PKG_ARGS_ARTIFACT)
|
||||
set(pkg_url
|
||||
${pkg_git_url}/releases/download/${PKG_ARGS_TAG}/${PKG_ARGS_ARTIFACT})
|
||||
"${pkg_git_url}/releases/download/${PKG_ARGS_TAG}/${PKG_ARGS_ARTIFACT}")
|
||||
else()
|
||||
set(pkg_url
|
||||
${pkg_git_url}/archive/refs/tags/${PKG_ARGS_TAG}.tar.gz)
|
||||
@@ -625,7 +695,8 @@ function(AddCIPackage)
|
||||
endif()
|
||||
|
||||
if (DEFINED pkgname AND NOT "${pkgname}" IN_LIST DISABLED_PLATFORMS)
|
||||
set(ARTIFACT "${ARTIFACT_NAME}-${pkgname}-${ARTIFACT_VERSION}.${ARTIFACT_EXT}")
|
||||
set(ARTIFACT
|
||||
"${ARTIFACT_NAME}-${pkgname}-${ARTIFACT_VERSION}.${ARTIFACT_EXT}")
|
||||
|
||||
AddPackage(
|
||||
NAME ${ARTIFACT_PACKAGE}
|
||||
|
||||
@@ -8,20 +8,26 @@
|
||||
include(GetSCMRev)
|
||||
|
||||
function(get_timestamp _var)
|
||||
string(TIMESTAMP timestamp UTC)
|
||||
set(${_var} "${timestamp}" PARENT_SCOPE)
|
||||
string(TIMESTAMP timestamp UTC)
|
||||
set(${_var} "${timestamp}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
get_timestamp(BUILD_DATE)
|
||||
|
||||
if (DEFINED GIT_RELEASE)
|
||||
set(BUILD_VERSION "${GIT_TAG}")
|
||||
set(GIT_REFSPEC "${GIT_RELEASE}")
|
||||
set(IS_DEV_BUILD false)
|
||||
set(BUILD_VERSION "${GIT_TAG}")
|
||||
set(GIT_REFSPEC "${GIT_RELEASE}")
|
||||
set(IS_DEV_BUILD false)
|
||||
else()
|
||||
string(SUBSTRING ${GIT_COMMIT} 0 10 BUILD_VERSION)
|
||||
set(BUILD_VERSION "${BUILD_VERSION}-${GIT_REFSPEC}")
|
||||
set(IS_DEV_BUILD true)
|
||||
string(SUBSTRING ${GIT_COMMIT} 0 10 BUILD_VERSION)
|
||||
set(BUILD_VERSION "${BUILD_VERSION}-${GIT_REFSPEC}")
|
||||
set(IS_DEV_BUILD true)
|
||||
endif()
|
||||
|
||||
if (NIGHTLY_BUILD)
|
||||
set(IS_NIGHTLY_BUILD true)
|
||||
else()
|
||||
set(IS_NIGHTLY_BUILD false)
|
||||
endif()
|
||||
|
||||
set(GIT_DESC ${BUILD_VERSION})
|
||||
@@ -30,15 +36,18 @@ set(GIT_DESC ${BUILD_VERSION})
|
||||
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
|
||||
|
||||
# Auto-updater metadata! Must somewhat mirror GitHub API endpoint
|
||||
set(BUILD_AUTO_UPDATE_WEBSITE "https://github.com")
|
||||
set(BUILD_AUTO_UPDATE_API "http://api.github.com")
|
||||
|
||||
if (NIGHTLY_BUILD)
|
||||
set(BUILD_AUTO_UPDATE_REPO "Eden-CI/Nightly")
|
||||
set(REPO_NAME "Eden Nightly")
|
||||
set(BUILD_AUTO_UPDATE_WEBSITE "https://github.com")
|
||||
set(BUILD_AUTO_UPDATE_API "api.github.com")
|
||||
set(BUILD_AUTO_UPDATE_API_PATH "/repos/")
|
||||
set(BUILD_AUTO_UPDATE_REPO "Eden-CI/Nightly")
|
||||
set(REPO_NAME "Eden Nightly")
|
||||
else()
|
||||
set(BUILD_AUTO_UPDATE_REPO "eden-emulator/Releases")
|
||||
set(REPO_NAME "Eden")
|
||||
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
|
||||
set(BUILD_AUTO_UPDATE_API "git.eden-emu.dev")
|
||||
set(BUILD_AUTO_UPDATE_API_PATH "/api/v1/repos/")
|
||||
set(BUILD_AUTO_UPDATE_REPO "eden-emu/eden")
|
||||
set(REPO_NAME "Eden")
|
||||
endif()
|
||||
|
||||
set(BUILD_ID ${GIT_REFSPEC})
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="https://git.eden-emu.dev/eden-emu/eden"><img src="./dist/qt_themes/default/icons/256x256/eden_named.png" alt="Eden" width="200"></a>
|
||||
<a href="https://git.eden-emu.dev/eden-emu/eden"><img src="./dist/qt_themes/default/icons/256x256/eden.png" alt="Eden" width="200"></a>
|
||||
<br>
|
||||
<b>Eden</b>
|
||||
<br>
|
||||
|
||||
@@ -5,21 +5,19 @@
|
||||
"name": "openssl",
|
||||
"repo": "crueter-ci/OpenSSL",
|
||||
"version": "3.6.0-1cb0d36b39",
|
||||
"min_version": "1.1.1"
|
||||
"min_version": "3"
|
||||
},
|
||||
"boost": {
|
||||
"package": "Boost",
|
||||
"repo": "boostorg/boost",
|
||||
"tag": "boost-%VERSION%",
|
||||
"artifact": "%TAG%-cmake.tar.xz",
|
||||
"hash": "4fb7f6fde92762305aad8754d7643cd918dd1f3f67e104e9ab385b18c73178d72a17321354eb203b790b6702f2cf6d725a5d6e2dfbc63b1e35f9eb59fb42ece9",
|
||||
"git_version": "1.89.0",
|
||||
"hash": "6ae6e94664fe7f2fb01976b59b276ac5df8085c7503fa829d810fbfe495960cfec44fa2c36e2cb23480bc19c956ed199d4952b02639a00a6c07625d4e7130c2d",
|
||||
"git_version": "1.90.0",
|
||||
"version": "1.57",
|
||||
"find_args": "CONFIG OPTIONAL_COMPONENTS headers context system fiber filesystem",
|
||||
"patches": [
|
||||
"0001-clang-cl.patch",
|
||||
"0002-use-marmasm.patch",
|
||||
"0003-armasm-options.patch"
|
||||
"0001-clang-cl.patch"
|
||||
]
|
||||
},
|
||||
"fmt": {
|
||||
@@ -48,9 +46,9 @@
|
||||
"package": "ZLIB",
|
||||
"repo": "madler/zlib",
|
||||
"tag": "v%VERSION%",
|
||||
"hash": "8c9642495bafd6fad4ab9fb67f09b268c69ff9af0f4f20cf15dfc18852ff1f312bd8ca41de761b3f8d8e90e77d79f2ccacd3d4c5b19e475ecf09d021fdfe9088",
|
||||
"hash": "06eaa3a1eaaeb31f461a2283b03a91ed8eb2406e62cd97ea1c69836324909edeecd93edd03ff0bf593d9dde223e3376149134c5b1fe2e8688c258cadf8cd60ff",
|
||||
"version": "1.2",
|
||||
"git_version": "1.3.1",
|
||||
"git_version": "1.3.1.2",
|
||||
"options": [
|
||||
"ZLIB_BUILD_SHARED OFF",
|
||||
"ZLIB_INSTALL OFF"
|
||||
@@ -103,5 +101,18 @@
|
||||
"git_version": "1.4.335.0",
|
||||
"artifact": "android-binaries-%VERSION%.zip",
|
||||
"hash": "48167c4a17736301bd08f9290f41830443e1f18cce8ad867fc6f289b49e18b40e93c9850b377951af82f51b5b6d7313aa6a884fc5df79f5ce3df82696c1c1244"
|
||||
},
|
||||
"quazip": {
|
||||
"package": "QuaZip-Qt6",
|
||||
"repo": "stachenov/quazip",
|
||||
"sha": "2e95c9001b",
|
||||
"hash": "609c240c7f029ac26a37d8fbab51bc16284e05e128b78b9b9c0e95d083538c36047a67d682759ac990e4adb0eeb90f04f1ea7fe2253bbda7e7e3bcce32e53dd8",
|
||||
"version": "1.3",
|
||||
"git_version": "1.5",
|
||||
"options": [
|
||||
"QUAZIP_QT_MAJOR_VERSION 6",
|
||||
"QUAZIP_INSTALL OFF",
|
||||
"QUAZIP_ENABLE_QTEXTCODEC OFF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,225 +6,191 @@
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg7"
|
||||
sodipodi:docname="base.svg.2026_01_12_14_43_47.0.svg"
|
||||
inkscape:version="1.4.2 (ebf0e94, 2025-05-08)"
|
||||
inkscape:export-filename="base.svg.2026_01_12_14_43_47.0.svg"
|
||||
sodipodi:docname="saintpatrick2026_named.svg"
|
||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||
xml:space="preserve"
|
||||
inkscape:export-filename="dev.eden_emu.eden.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata1">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Madeline_Dev</dc:title>
|
||||
<dc:identifier>mailto:madelvidel@gmail.com</dc:identifier>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:date>2025</dc:date>
|
||||
<dc:license
|
||||
rdf:resource="https://www.gnu.org/licenses/gpl-3.0.html" />
|
||||
<dc:rights>2025 Eden Emulator Project</dc:rights>
|
||||
<dc:source>https://git.eden-emu.dev</dc:source>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs7">
|
||||
<linearGradient
|
||||
id="linearGradient1"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#ff2e88;stop-opacity:0.5;"
|
||||
offset="0"
|
||||
id="stop3" />
|
||||
<stop
|
||||
style="stop-color:#bf42f6;stop-opacity:0.5;"
|
||||
offset="0.44631511"
|
||||
id="stop4" />
|
||||
<stop
|
||||
style="stop-color:#5da5ed;stop-opacity:0.5;"
|
||||
offset="0.90088946"
|
||||
id="stop2" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient138"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#ff2e88;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop152" />
|
||||
<stop
|
||||
style="stop-color:#bf42f6;stop-opacity:1;"
|
||||
offset="0.44971901"
|
||||
id="stop137" />
|
||||
<stop
|
||||
style="stop-color:#5da5ed;stop-opacity:1;"
|
||||
offset="0.89793283"
|
||||
id="stop138" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch37"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop37" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch28"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#252525;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop28" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch27"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop27" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch15"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop16" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient14"
|
||||
inkscape:swatch="gradient">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop14" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop15" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch9"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop10" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch8"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop9" />
|
||||
</linearGradient>
|
||||
<rect
|
||||
x="22.627417"
|
||||
y="402.76802"
|
||||
width="521.34025"
|
||||
height="248.94868"
|
||||
id="rect24" />
|
||||
<linearGradient
|
||||
id="linearGradient11"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#ff2e88;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop11" />
|
||||
<stop
|
||||
style="stop-color:#bf42f6;stop-opacity:1;"
|
||||
offset="0.44971901"
|
||||
id="stop154" />
|
||||
<stop
|
||||
style="stop-color:#5da5ed;stop-opacity:1;"
|
||||
offset="0.89793283"
|
||||
id="stop12" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient138"
|
||||
id="linearGradient6"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.118028,0,0,1.116699,-46.314723,-42.388667)"
|
||||
x1="270.39996"
|
||||
y1="40.000019"
|
||||
x2="270.39996"
|
||||
y2="494.39996"
|
||||
spreadMethod="pad" />
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath18">
|
||||
<circle
|
||||
style="opacity:1;mix-blend-mode:normal;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.8382;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
||||
id="circle18"
|
||||
cx="-246.8315"
|
||||
cy="246.8338"
|
||||
inkscape:label="Circle"
|
||||
r="191.89999" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath22">
|
||||
<circle
|
||||
style="opacity:1;mix-blend-mode:normal;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.8382;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
||||
id="circle22"
|
||||
cx="256"
|
||||
cy="256"
|
||||
inkscape:label="Circle"
|
||||
r="191.89999" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient11"
|
||||
id="linearGradient27"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-6.9401139e-5,-2.8678628)"
|
||||
x1="256.00012"
|
||||
y1="102.94693"
|
||||
x2="256.00012"
|
||||
y2="409.05307" />
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath128">
|
||||
<circle
|
||||
style="fill:none;fill-opacity:1;stroke:#03ffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle128"
|
||||
cx="256"
|
||||
cy="256"
|
||||
r="192" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1"
|
||||
id="linearGradient2"
|
||||
x1="256"
|
||||
y1="64"
|
||||
x2="256"
|
||||
y2="448"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.3229974,0,0,1.3214002,-82.687336,-82.290326)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="261.62951"
|
||||
inkscape:cy="230.87036"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1008"
|
||||
inkscape:window-x="1080"
|
||||
inkscape:window-y="351"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7" />
|
||||
<path
|
||||
id="path8-7"
|
||||
style="display:inline;mix-blend-mode:multiply;fill:url(#linearGradient6);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2);stroke-width:3.9666;stroke-dasharray:none;stroke-opacity:0.566238;paint-order:stroke fill markers"
|
||||
inkscape:label="Circle"
|
||||
d="M 256,2.2792898 A 254.0155,253.71401 0 0 0 150.68475,25.115202 c 19.54414,1.070775 38.74692,5.250294 51.56848,11.647658 14.14361,7.056691 28.63804,19.185961 39.4212,29.347551 h 40.60981 c 1.03847,-0.68139 2.10297,-1.36938 3.1938,-2.05957 5.45602,-15.78533 14.79164,-43.183497 19.49612,-57.0097682 A 254.0155,253.71401 0 0 0 256,2.2792898 Z m 61.57106,7.567234 -18.26098,46.1544672 c 7.79702,-4.13918 16.35655,-7.87447 25.20671,-10.87081 23.1229,-7.828433 43.96931,-10.170904 54.94058,-10.868226 A 254.0155,253.71401 0 0 0 317.57106,9.8465238 Z m 65.39277,26.4001532 c -9.68256,4.806644 -33.05532,16.642034 -55.68217,29.863734 H 424.4677 A 254.0155,253.71401 0 0 0 382.96383,36.246677 Z M 113.90698,45.690231 A 254.0155,253.71401 0 0 0 87.532302,66.110411 H 194.2739 c -1.47402,-0.80231 -2.35141,-1.25949 -2.35141,-1.25949 l 10.4496,-11.83348 -38.40568,7.01234 c 0,1e-5 -12.21537,-4.60266 -40.17313,-12.27223 -3.45336,-0.94731 -6.75329,-1.61824 -9.8863,-2.06732 z m -36.803618,30.18635 a 254.0155,253.71401 0 0 0 -34.88372,43.090929 h 59.976738 c 18.11461,-12.04145 40.14252,-22.882149 62.31266,-24.534159 52.93006,-3.9444 70.16538,1.86342 70.16538,1.86342 0,0 -4.612,-4.8206 -14.51938,-13.36656 -2.72366,-2.34942 -6.0844,-4.77373 -9.52455,-7.05363 z m 174.472868,0 c 4.57322,4.7186 7.29716,7.83565 7.29716,7.83565 0,0 3.53501,-3.18484 9.62532,-7.83565 z m 60.27649,0 c -21.56573,15.45339 -25.4703,27.979669 -25.4703,27.979669 0,0 54.83326,-19.215729 100.70543,-0.31228 11.63986,4.79661 21.58481,10.13159 29.94832,15.42354 h 52.74419 A 254.0155,253.71401 0 0 0 434.89664,75.876581 Z M 36.250648,128.73367 A 254.0155,253.71401 0 0 0 16.372095,171.82459 H 147.45478 c 1.45695,-2.5815 3.06539,-5.08648 4.83979,-7.48982 14.23694,-19.28301 27.92088,-30.0088 36.86047,-35.6011 h -30.25323 c -5.87346,0.93472 -12.04945,1.99094 -18.28166,3.16937 -30.12936,5.69727 -81.157618,22.78945 -81.157618,22.78945 0,0 11.47125,-12.39249 29.11369,-25.95882 z m 265.630492,0 c 33.48676,11.2434 52.42799,26.78443 62.7752,43.09092 h 130.97157 a 254.0155,253.71401 0 0 0 -19.87856,-43.09092 h -44.81136 c 14.85233,11.5863 21.59948,20.9854 21.59948,20.9854 0,0 -33.5226,-12.37087 -66.0646,-20.9854 z m -45.96641,16.27007 c -1.00419,0.0106 -10.12705,0.72026 -44.98966,20.64729 -3.12132,1.78406 -6.25434,3.86182 -9.37468,6.17356 h 41.81911 c 7.17181,-17.34774 12.64083,-26.82085 12.64083,-26.82085 0,0 -0.0287,-7.1e-4 -0.0957,0 z m 14.18088,0.0465 c 0,0 -3.31228,9.32762 -7.30492,26.77438 h 51.78554 C 287.6577,146.14158 270.09561,145.0502 270.09561,145.0502 Z M 13.152456,181.59075 A 254.0155,253.71401 0 0 0 3.927651,224.68167 H 134.1447 c 0.56161,-12.72411 2.67825,-28.50188 8.61499,-43.09092 z m 176.661504,0 c -14.27121,13.10564 -27.60733,29.58761 -37.56073,43.09092 h 73.3721 c 4.47018,-16.79061 9.35068,-31.26371 13.86562,-43.09092 z m 70.85787,0 c -2.41384,11.76417 -4.9032,26.20707 -6.94831,43.09092 H 360.4832 c -8.32133,-10.88917 -20.66988,-26.17008 -36.35141,-43.09092 z m 109.17313,0 c 6.63611,15.24089 6.92441,30.5373 5.57882,43.09092 h 132.64857 a 254.0155,253.71401 0 0 0 -9.22481,-43.09092 z M 2.90181,234.44783 A 254.0155,253.71401 0 0 0 1.984498,255.9933 254.0155,253.71401 0 0 0 2.90181,277.53876 h 211.89923 c 2.25762,-15.52555 5.14325,-29.93448 8.3385,-43.09093 h -77.8863 c -6.46396,9.27617 -10.33076,15.56549 -10.33076,15.56549 0,0 -0.82623,-6.14945 -0.9354,-15.56549 z m 249.72093,0 c -1.3692,13.09684 -2.4456,27.49209 -3.02068,43.09093 h 259.49613 a 254.0155,253.71401 0 0 0 0.91731,-21.54546 254.0155,253.71401 0 0 0 -0.91731,-21.54547 H 374.02584 c -0.445,2.5469 -0.90878,4.89768 -1.32817,7.01751 0,0 -1.69726,-2.53821 -4.94056,-7.01751 z M 3.927651,287.30493 a 254.0155,253.71401 0 0 0 9.224805,43.09091 H 214.04393 c -1.29238,-15.40742 -1.57503,-30.04388 -0.41861,-43.09091 z m 245.385009,0 c -0.30355,13.54349 -0.22032,27.92598 0.36951,43.09091 h 249.16537 a 254.0155,253.71401 0 0 0 9.22481,-43.09091 z M 16.369511,340.16201 a 254.0155,253.71401 0 0 0 19.878554,43.09091 H 221.4677 c -2.69781,-14.4523 -4.96108,-29.01285 -6.4832,-43.09091 z m 233.842379,0 c 1.15864,15.47765 3.81286,29.83979 7.51679,43.09091 h 218.02325 a 254.0155,253.71401 0 0 0 19.87856,-43.09091 z M 42.217052,393.01909 a 254.0155,253.71401 0 0 0 34.88372,43.09093 H 233.09561 c -3.40902,-13.67281 -6.76794,-28.2531 -9.73902,-43.09093 z m 218.490958,0 c 5.34985,16.15926 12.22007,30.51982 19.68733,43.09093 h 154.50389 a 254.0155,253.71401 0 0 0 34.88371,-43.09093 z M 87.529722,445.87618 a 254.0155,253.71401 0 0 0 166.229968,63.8208 c -3.67805,-12.0825 -10.85464,-35.49828 -18.18088,-63.8208 z m 199.010328,0 c 17.5887,26.43772 36.99259,43.60598 47.33592,51.61309 a 254.0155,253.71401 0 0 0 90.59431,-51.61309 z" />
|
||||
<path
|
||||
id="path27"
|
||||
style="display:inline;mix-blend-mode:multiply;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient27);stroke-width:3;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
d="m 318.98012,441.7375 c -9.87518,-6.73978 -64.39137,-49.0272 -67.68975,-127.81978 -3.69298,-88.21893 15.36468,-141.91029 15.36468,-141.91029 0,0 16.00378,0.99513 39.80316,26.53195 23.79939,25.53753 37.74965,46.43102 37.74965,46.43102 3.91262,-19.79992 12.84563,-66.32402 -60.72865,-87.55523 0,0 12.82326,-5.38883 39.3925,-3.81382 26.56907,1.57572 81.6822,21.93799 81.6822,21.93799 0,0 -14.79766,-20.63773 -49.47063,-34.94295 -34.67291,-14.30533 -76.1182,0.23644 -76.1182,0.23644 0,0 3.86959,-12.43127 27.22669,-26.38478 23.35718,-13.9537 49.27409,-26.501533 49.27409,-26.501533 0,0 -21.97854,-0.26548 -47.67725,8.44535 -6.68948,2.267506 -13.15863,5.094213 -19.05208,8.226563 l 16.05803,-40.634103 -4.4617,-1.89059 -5.1305,-0.95965 c 0,0 -11.24072,33.12428 -16.92051,49.576513 -12.13137,7.68489 -20.11005,14.87735 -20.11005,14.87735 0,0 -21.90573,-25.09227 -42.79668,-35.527803 -26.03412,-13.00525 -86.88249,-13.90359 -94.0044,10.401173 0,0 13.56804,-7.884703 34.70032,-2.080917 21.13214,5.803997 30.3644,9.287307 30.3644,9.287307 l 29.02989,-5.30681 -7.89811,8.95527 c 0,0 13.8496,7.21324 21.33822,13.68063 7.48859,6.46722 10.9757,10.11472 10.9757,10.11472 0,0 -13.02739,-4.39388 -53.03507,-1.40893 -40.00771,2.98473 -79.40016,45.60209 -79.40016,45.60209 0,0 38.57037,-12.93531 61.34393,-17.24677 22.77354,-4.31126 44.52166,-6.46757 44.52166,-6.46757 0,0 -17.23298,5.97003 -35.69792,31.00932 -18.46522,25.03987 -13.13146,64.83866 -13.13146,64.83866 0,0 29.33874,-47.7577 57.44675,-63.84249 28.10798,-16.08527 34.0799,-15.6238 34.0799,-15.6238 0,0 -22.56785,39.13486 -31.39017,101.98268 -8.03005,57.2039 26.77689,163.75449 31.1572,178.89699"
|
||||
sodipodi:nodetypes="cscsccscscscsccccccscscccscscscscscsc"
|
||||
inkscape:label="MainOutline"
|
||||
clip-path="url(#clipPath128)"
|
||||
transform="matrix(1.3229974,0,0,1.3214002,-82.687282,-82.278451)" />
|
||||
</svg>
|
||||
id="defs7"><linearGradient
|
||||
id="swatch14"
|
||||
inkscape:swatch="solid"><stop
|
||||
style="stop-color:#66003b;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop14" /></linearGradient><linearGradient
|
||||
id="linearGradient11"
|
||||
inkscape:collect="always"><stop
|
||||
style="stop-color:#f6d512;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop11" /><stop
|
||||
style="stop-color:#1d8e53;stop-opacity:1;"
|
||||
offset="0.99898213"
|
||||
id="stop20" /><stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="0.99898213"
|
||||
id="stop12" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient11"
|
||||
id="linearGradient12"
|
||||
x1="109.74531"
|
||||
y1="106.54533"
|
||||
x2="431.05463"
|
||||
y2="427.85461"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
spreadMethod="reflect"
|
||||
gradientTransform="matrix(1.0945321,0,0,1.0945321,-39.661525,-35.159057)" /><filter
|
||||
inkscape:label="Light Contour"
|
||||
inkscape:menu="Image Paint and Draw"
|
||||
inkscape:menu-tooltip="Uses vertical specular light to draw lines"
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter11"
|
||||
x="-0.01907517"
|
||||
y="-0.054959154"
|
||||
width="1.0379885"
|
||||
height="1.1092314"><feGaussianBlur
|
||||
in="SourceGraphic"
|
||||
stdDeviation="0.38250006"
|
||||
result="result3"
|
||||
id="feGaussianBlur9" /><feComponentTransfer
|
||||
result="result1"
|
||||
in="result3"
|
||||
id="feComponentTransfer9"><feFuncR
|
||||
type="discrete"
|
||||
tableValues="0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1"
|
||||
id="feFuncR9" /><feFuncG
|
||||
type="discrete"
|
||||
tableValues="0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1"
|
||||
id="feFuncG9" /><feFuncB
|
||||
type="discrete"
|
||||
tableValues="0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1"
|
||||
id="feFuncB9" /></feComponentTransfer><feGaussianBlur
|
||||
result="result5"
|
||||
stdDeviation="0.01"
|
||||
id="feGaussianBlur10" /><feBlend
|
||||
in2="result5"
|
||||
result="result6"
|
||||
mode="lighten"
|
||||
in="result5"
|
||||
id="feBlend10" /><feColorMatrix
|
||||
in="result6"
|
||||
type="luminanceToAlpha"
|
||||
result="result2"
|
||||
id="feColorMatrix10" /><feSpecularLighting
|
||||
surfaceScale="5"
|
||||
result="result9"
|
||||
specularExponent="20"
|
||||
in="result2"
|
||||
specularConstant="1"
|
||||
id="feSpecularLighting10"><feDistantLight
|
||||
azimuth="180"
|
||||
elevation="90"
|
||||
id="feDistantLight10" /></feSpecularLighting><feComposite
|
||||
in2="result6"
|
||||
operator="arithmetic"
|
||||
in="result9"
|
||||
k1="0.4"
|
||||
k3="0.7"
|
||||
result="result3"
|
||||
id="feComposite10"
|
||||
k2="0"
|
||||
k4="0" /><feBlend
|
||||
in2="result1"
|
||||
in="result3"
|
||||
mode="normal"
|
||||
result="result8"
|
||||
id="feBlend11" /><feComposite
|
||||
in2="SourceGraphic"
|
||||
in="result8"
|
||||
operator="in"
|
||||
result="result7"
|
||||
id="feComposite11" /></filter></defs><sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="0.6363961"
|
||||
inkscape:cx="172.06265"
|
||||
inkscape:cy="122.56518"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="849"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7"
|
||||
showguides="false" /><circle
|
||||
style="fill:url(#linearGradient12);fill-opacity:1;stroke:#e4e4e4;stroke-width:14.0448;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="path8"
|
||||
cx="256.2999"
|
||||
cy="257.2999"
|
||||
r="248.67769" /><path
|
||||
id="path15"
|
||||
style="fill:#f3ffeb;fill-opacity:1;stroke:#ffffff;stroke-width:16.9642;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.33910036;paint-order:stroke fill markers"
|
||||
d="m 306.72111,24.233031 c 0,0 -11.98397,40.08696 -18.0546,60.431848 -12.96613,9.503601 -21.49377,18.397701 -21.49377,18.397701 0,0 -23.41313,-31.029398 -45.74145,-43.934598 -22.32833,-12.905201 -52.42065,-11.242483 -52.42065,-11.242483 0,0 -12.50052,4e-4 -27.63117,5.537132 -15.13066,5.536732 -21.27107,9.227888 -21.27107,9.227888 0,0 15.35165,-0.410529 37.93799,6.766716 22.58635,7.177243 32.45374,11.484796 32.45374,11.484796 l 31.02752,-6.562453 -8.44161,11.074275 c 0,0 14.80259,8.920284 22.80648,16.917787 8.0039,7.9975 11.73088,12.50812 11.73088,12.50812 0,0 -13.92373,-5.43341 -56.68427,-1.74226 -42.76055,3.69116 -84.86368,56.39265 -84.86368,56.39265 0,0 41.22428,-15.9958 65.5649,-21.32747 24.34062,-5.33166 47.58524,-7.9983 47.58524,-7.9983 0,0 -18.41865,7.3827 -38.15428,38.3474 -19.73564,30.96468 -14.0351,80.18128 -14.0351,80.18128 0,0 31.35774,-59.05848 61.39977,-78.94969 30.04203,-19.89124 36.182,-20.50642 36.182,-20.50642 0,0 -24.1209,48.39514 -33.55015,126.11445 -9.42924,77.71931 30.26089,207.72959 30.26089,207.72959 l 47.80367,-6.97298 c 0,0 -45.61041,-42.24281 -49.55753,-151.33695 -3.94713,-109.09413 16.66479,-174.30453 16.66479,-174.30453 0,0 17.10508,1.23039 42.54213,32.81027 25.43704,31.57987 40.34713,57.41795 40.34713,57.41795 0,0 9.65024,-51.26683 -11.4011,-74.64415 -21.05135,-23.3773 -53.50637,-33.62931 -53.50637,-33.62931 0,0 13.70573,-6.66419 42.10313,-4.71609 28.39738,1.94813 87.30278,27.12897 87.30278,27.12896 0,0 -15.8158,-25.5214 -52.87463,-43.21167 -37.05881,-17.69028 -81.35597,0.29238 -81.35597,0.29238 0,0 4.13589,-15.37277 29.10021,-32.628037 24.96432,-17.25527 56.907,-34.36427 56.907,-34.36427 0,0 -26.3595,1.160335 -55.20025,12.035504 -7.176,2.7059 -14.064,6.299542 -20.36309,10.173104 l 17.40574,-51.051762 z" /><path
|
||||
d="m 364.02341,369.59545 c -1.05628,0.0923 -4.67136,0.65996 -7.06652,1.09993 -1.73317,0.31934 -2.17946,0.41869 -2.99769,0.68125 -0.51326,0.15613 -0.62485,0.17032 -0.91495,0.0993 -0.43144,-0.10644 -2.3208,-0.2058 -4.86474,-0.26256 -4.47793,-0.10645 -6.76898,0.3761 -9.18647,1.91601 -1.68109,1.07865 -2.9754,2.40567 -4.18788,4.3075 -0.72897,1.14251 -0.92234,2.15729 -0.77357,4.17266 0.11901,1.59667 0.37935,2.58307 1.19757,4.54877 1.61417,3.84622 3.75641,6.6209 9.60302,12.41863 4.25482,4.22943 5.65324,5.72676 5.65324,6.07449 0,0.15612 -0.0298,0.17031 -0.40911,0.17031 -0.52812,0 -0.77362,-0.0993 -1.69599,-0.69545 -1.0711,-0.68834 -2.31333,-1.61087 -4.66389,-3.46302 -3.42913,-2.69661 -3.92749,-3.07982 -5.19948,-4.02364 -2.0307,-1.49024 -3.6374,-2.49082 -4.74571,-2.95209 -1.8968,-0.78769 -5.02097,-1.24895 -7.31945,-1.07864 -2.68526,0.20579 -4.72343,0.85866 -6.76156,2.16438 -1.98605,1.28445 -5.15484,4.17977 -5.58628,5.11648 -0.29009,0.62448 -0.46118,1.93022 -0.59505,4.4991 -0.11158,2.05794 -0.0373,3.37077 0.29011,5.40033 l 0.20083,1.24187 -0.45376,1.59667 c -0.70663,2.45535 -0.95956,4.18686 -1.04882,6.95444 -0.0819,2.76759 0.19338,4.45651 0.94467,5.90417 0.97445,1.85925 3.83081,4.98875 5.91358,6.46479 1.23478,0.87994 2.98284,1.48315 5.09534,1.7599 1.10831,0.14903 3.4663,0.12773 4.23992,-0.0355 1.02649,-0.21289 2.61833,-0.73092 3.39936,-1.10704 1.47284,-0.70253 3.91264,-2.36308 6.97727,-4.75455 4.66392,-3.63334 6.5235,-5.01713 7.28968,-5.40744 0.3868,-0.20579 0.51327,-0.23417 1.00417,-0.23417 0.49094,0 0.60253,0.0284 0.94471,0.21289 l 0.37936,0.21999 -1.78522,1.76698 c -8.50216,8.44468 -9.78157,9.89943 -11.44034,13.02184 -1.42817,2.69662 -2.41749,5.54225 -2.78942,8.01888 -0.23059,1.5825 -0.0892,4.59135 0.29753,6.03192 0.28267,1.06444 0.78846,2.24244 1.24966,2.87403 0.6546,0.90832 1.65877,2.09341 1.76292,2.09341 0.2901,0 1.77778,-1.12122 2.11996,-1.59668 0.14134,-0.1916 0.31243,-0.49673 0.37936,-0.67415 0.17852,-0.47546 0.20827,-1.52571 0.0744,-2.79596 -0.15619,-1.46186 -0.15619,-3.64754 -0.007,-4.48491 0.14877,-0.81607 0.60996,-2.44825 1.03396,-3.61204 0.78105,-2.18569 1.71829,-3.94559 3.35473,-6.31577 1.65877,-2.39857 4.64161,-6.0319 6.28548,-7.65697 0.66203,-0.65287 2.0456,-1.73151 2.12743,-1.66056 0.0297,0.0355 -0.61742,1.5683 -1.2199,2.85984 -0.41659,0.90123 -1.32407,2.62566 -2.13486,4.04493 -1.4505,2.54049 -1.98605,3.66882 -2.16458,4.55586 -0.29009,1.45476 -0.43143,3.34239 -0.43143,5.76934 0,2.12891 0.0147,2.48374 0.16362,3.40625 0.19341,1.15672 0.54301,2.77469 0.76619,3.49851 0.51322,1.67475 1.71084,3.49141 3.25803,4.94616 1.56209,1.47606 2.98283,2.16441 5.43008,2.63985 0.83307,0.15613 1.04881,0.16322 3.46631,0.0993 2.26129,-0.0639 2.98283,-0.23417 6.02513,-1.39088 1.74807,-0.66706 2.57372,-0.94382 3.64486,-1.22767 2.96051,-0.7806 5.22924,-0.9864 6.96983,-0.63158 0.78848,0.16322 0.7959,0.16322 1.07858,0.0284 0.15619,-0.0781 0.81822,-0.30515 1.46536,-0.50385 0.6546,-0.1987 1.4505,-0.49674 1.77778,-0.66705 2.14971,-1.09285 6.40453,-4.93907 7.26737,-6.57833 0.66945,-1.27735 1.17528,-3.87462 1.09345,-5.64871 -0.10415,-2.18568 -0.78103,-4.1017 -2.3059,-6.52156 -0.95956,-1.53281 -1.7555,-2.44825 -3.76387,-4.36426 -1.78521,-1.70313 -3.14646,-2.85984 -6.8136,-5.81901 -4.55235,-3.66173 -6.17394,-5.06681 -6.12187,-5.30809 0.0151,-0.071 0.0819,-0.11354 0.17109,-0.0993 0.27521,0.0497 1.85962,1.06446 6.00286,3.85334 4.28453,2.88111 6.06231,3.92428 7.81781,4.60554 3.94235,1.51151 8.04839,2.29922 11.44773,2.17857 1.95634,-0.0639 3.31758,-0.36901 4.85734,-1.08575 0.88516,-0.41157 2.40259,-1.3625 3.49606,-2.19986 1.07115,-0.81608 3.03487,-2.68952 3.51838,-3.34949 0.97443,-1.3412 1.65877,-3.95977 1.55462,-5.94674 -0.0595,-1.08575 -0.25287,-1.90184 -0.93723,-4.04494 -0.69179,-2.16438 -1.15298,-3.77526 -1.28684,-4.4636 -0.15624,-0.82319 -0.11901,-3.30691 0.0819,-4.8965 0.20827,-1.66764 0.28263,-4.11589 0.16362,-5.10938 -0.18594,-1.52571 -0.6397,-3.1153 -1.23476,-4.34298 -0.99674,-2.05794 -3.33244,-4.20814 -5.7276,-5.27968 -1.41332,-0.62449 -3.4961,-1.09994 -5.89127,-1.34831 -1.24965,-0.12065 -3.91264,-0.0497 -5.04324,0.14192 -1.815,0.30515 -4.71601,1.09994 -5.31849,1.44766 -0.80337,0.46836 -2.80432,2.24955 -7.21533,6.39382 -1.77778,1.67474 -3.8531,3.60496 -4.61181,4.28621 -1.24966,1.12832 -2.1051,1.79538 -2.19437,1.71022 -0.0967,-0.0993 1.34635,-2.19987 4.90939,-7.16023 4.95399,-6.89057 5.67552,-8.06147 6.44171,-10.41036 1.12318,-3.47012 0.052,-8.16082 -2.67041,-11.73029 -0.8852,-1.15671 -2.05303,-2.05085 -3.73412,-2.86694 -1.43561,-0.69544 -2.86379,-1.12122 -4.53745,-1.3554 -0.75872,-0.10644 -4.11344,-0.1987 -4.83498,-0.13482 z"
|
||||
id="path1"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00726536" /><path
|
||||
d="m 83.20673,250.24331 c -1.05628,0.0923 -4.67136,0.65996 -7.06652,1.09993 -1.73317,0.31934 -2.17946,0.41869 -2.99769,0.68125 -0.51326,0.15613 -0.62485,0.17032 -0.91495,0.0993 -0.43144,-0.10644 -2.3208,-0.2058 -4.86474,-0.26256 -4.47793,-0.10645 -6.76898,0.3761 -9.18647,1.91601 -1.68109,1.07865 -2.9754,2.40567 -4.18788,4.3075 -0.72897,1.14251 -0.92234,2.15729 -0.77357,4.17266 0.11901,1.59667 0.37935,2.58307 1.19757,4.54877 1.61417,3.84622 3.75641,6.6209 9.60302,12.41863 4.25482,4.22943 5.65324,5.72676 5.65324,6.07449 0,0.15612 -0.0298,0.17031 -0.40911,0.17031 -0.52812,0 -0.77362,-0.0993 -1.69599,-0.69545 -1.0711,-0.68834 -2.31333,-1.61087 -4.66389,-3.46302 -3.42913,-2.69661 -3.92749,-3.07982 -5.19948,-4.02364 -2.0307,-1.49024 -3.6374,-2.49082 -4.74571,-2.95209 -1.8968,-0.78769 -5.02097,-1.24895 -7.31945,-1.07864 -2.68526,0.20579 -4.72343,0.85866 -6.76156,2.16438 -1.98605,1.28445 -5.15484,4.17977 -5.58628,5.11648 -0.29009,0.62448 -0.46118,1.93022 -0.59505,4.4991 -0.11158,2.05794 -0.0373,3.37077 0.29011,5.40033 l 0.20083,1.24187 -0.45376,1.59667 c -0.70663,2.45535 -0.95956,4.18686 -1.04882,6.95444 -0.0819,2.76759 0.19338,4.45651 0.94467,5.90417 0.97445,1.85925 3.83081,4.98875 5.91358,6.46479 1.23478,0.87994 2.98284,1.48315 5.09534,1.7599 1.10831,0.14903 3.4663,0.12773 4.23992,-0.0355 1.02649,-0.21289 2.61833,-0.73092 3.39936,-1.10704 1.47284,-0.70253 3.91264,-2.36308 6.97727,-4.75455 4.66392,-3.63334 6.5235,-5.01713 7.28968,-5.40744 0.3868,-0.20579 0.51327,-0.23417 1.00417,-0.23417 0.49094,0 0.60253,0.0284 0.94471,0.21289 l 0.37936,0.21999 -1.78522,1.76698 c -8.50216,8.44468 -9.78157,9.89943 -11.44034,13.02184 -1.42817,2.69662 -2.41749,5.54225 -2.78942,8.01888 -0.23059,1.5825 -0.0892,4.59135 0.29753,6.03192 0.28267,1.06444 0.78846,2.24244 1.24966,2.87403 0.6546,0.90832 1.65877,2.09341 1.76292,2.09341 0.2901,0 1.77778,-1.12122 2.11996,-1.59668 0.14134,-0.1916 0.31243,-0.49673 0.37936,-0.67415 0.17852,-0.47546 0.20827,-1.52571 0.0744,-2.79596 -0.15619,-1.46186 -0.15619,-3.64754 -0.007,-4.48491 0.14877,-0.81607 0.60996,-2.44825 1.03396,-3.61204 0.78105,-2.18569 1.71829,-3.94559 3.35473,-6.31577 1.65877,-2.39857 4.64161,-6.0319 6.28548,-7.65697 0.66203,-0.65287 2.0456,-1.73151 2.12743,-1.66056 0.0297,0.0355 -0.61742,1.5683 -1.2199,2.85984 -0.41659,0.90123 -1.32407,2.62566 -2.13486,4.04493 -1.4505,2.54049 -1.98605,3.66882 -2.16458,4.55586 -0.29009,1.45476 -0.43143,3.34239 -0.43143,5.76934 0,2.12891 0.0147,2.48374 0.16362,3.40625 0.19341,1.15672 0.54301,2.77469 0.76619,3.49851 0.51322,1.67475 1.71084,3.49141 3.25803,4.94616 1.56209,1.47606 2.98283,2.16441 5.43008,2.63985 0.83307,0.15613 1.04881,0.16322 3.46631,0.0993 2.26129,-0.0639 2.98283,-0.23417 6.02513,-1.39088 1.74807,-0.66706 2.57372,-0.94382 3.64486,-1.22767 2.96051,-0.7806 5.22924,-0.9864 6.96983,-0.63158 0.78848,0.16322 0.7959,0.16322 1.07858,0.0284 0.15619,-0.0781 0.81822,-0.30515 1.46536,-0.50385 0.6546,-0.1987 1.4505,-0.49674 1.77778,-0.66705 2.14971,-1.09285 6.40453,-4.93907 7.26737,-6.57833 0.66945,-1.27735 1.17528,-3.87462 1.09345,-5.64871 -0.10415,-2.18568 -0.78103,-4.1017 -2.3059,-6.52156 -0.95956,-1.53281 -1.7555,-2.44825 -3.76387,-4.36426 -1.78521,-1.70313 -3.14646,-2.85984 -6.8136,-5.81901 -4.55235,-3.66173 -6.17394,-5.06681 -6.12187,-5.30809 0.0151,-0.071 0.0819,-0.11354 0.17109,-0.0993 0.27521,0.0497 1.85962,1.06446 6.00286,3.85334 4.28453,2.88111 6.06231,3.92428 7.81781,4.60554 3.94235,1.51151 8.04839,2.29922 11.44773,2.17857 1.95634,-0.0639 3.31758,-0.36901 4.85734,-1.08575 0.88516,-0.41157 2.40259,-1.3625 3.49606,-2.19986 1.07115,-0.81608 3.03487,-2.68952 3.51838,-3.34949 0.97443,-1.3412 1.65877,-3.95977 1.55462,-5.94674 -0.0595,-1.08575 -0.25287,-1.90184 -0.93723,-4.04494 -0.69179,-2.16438 -1.15298,-3.77526 -1.28684,-4.4636 -0.15624,-0.82319 -0.11901,-3.30691 0.0819,-4.8965 0.20827,-1.66764 0.28263,-4.11589 0.16362,-5.10938 -0.18594,-1.52571 -0.6397,-3.1153 -1.23476,-4.34298 -0.99674,-2.05794 -3.33244,-4.20814 -5.7276,-5.27968 -1.41332,-0.62449 -3.4961,-1.09994 -5.89127,-1.34831 -1.24965,-0.12065 -3.91264,-0.0497 -5.04324,0.14192 -1.815,0.30515 -4.71601,1.09994 -5.31849,1.44766 -0.80337,0.46836 -2.80432,2.24955 -7.21533,6.39382 -1.77778,1.67474 -3.8531,3.60496 -4.61181,4.28621 -1.24966,1.12832 -2.1051,1.79538 -2.19437,1.71022 -0.0967,-0.0993 1.34635,-2.19987 4.90939,-7.16023 4.95399,-6.89057 5.67552,-8.06147 6.44171,-10.41036 1.12318,-3.47012 0.052,-8.16082 -2.67041,-11.73029 -0.8852,-1.15671 -2.05303,-2.05085 -3.73412,-2.86694 -1.43561,-0.69544 -2.86379,-1.12122 -4.53745,-1.3554 -0.75872,-0.10644 -4.11344,-0.1987 -4.83498,-0.13482 z"
|
||||
id="path1-9"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00726536" /><path
|
||||
d="m 439.21947,248.58317 c -1.32752,0.12081 -5.87092,0.86387 -8.88113,1.43979 -2.17823,0.41802 -2.73912,0.54806 -3.76747,0.89175 -0.64506,0.20437 -0.7853,0.22295 -1.1499,0.12998 -0.54223,-0.13933 -2.91676,-0.26938 -6.11395,-0.34369 -5.62782,-0.13934 -8.50719,0.49231 -11.54547,2.50804 -2.11277,1.41194 -3.73945,3.14899 -5.26329,5.63847 -0.91615,1.49553 -1.15918,2.82387 -0.97221,5.46197 0.14957,2.09002 0.47676,3.38121 1.5051,5.9543 2.02866,5.03465 4.72101,8.66669 12.06898,16.25585 5.34741,5.53628 7.10493,7.49627 7.10493,7.95145 0,0.20436 -0.0375,0.22293 -0.51416,0.22293 -0.66374,0 -0.97228,-0.12998 -2.13151,-0.91034 -1.34614,-0.90103 -2.90737,-2.10861 -5.86153,-4.53305 -4.30969,-3.52984 -4.93603,-4.03145 -6.53465,-5.26691 -2.55217,-1.95071 -4.57145,-3.26045 -5.96436,-3.86425 -2.38388,-1.03107 -6.3103,-1.63487 -9.19901,-1.41193 -3.37482,0.26938 -5.93636,1.12398 -8.49786,2.83315 -2.49604,1.68134 -6.47855,5.47127 -7.02078,6.69742 -0.36459,0.81743 -0.57961,2.52664 -0.74785,5.88927 -0.14024,2.69383 -0.0469,4.4123 0.3646,7.06898 l 0.25241,1.6256 -0.57028,2.09002 c -0.8881,3.21403 -1.20598,5.48056 -1.31815,9.10329 -0.10293,3.62275 0.24303,5.83353 1.18725,7.7285 1.22468,2.43373 4.81452,6.53023 7.43213,8.46235 1.55185,1.15183 3.7488,1.94142 6.40377,2.30368 1.39291,0.19508 4.35641,0.16719 5.32868,-0.0464 1.29009,-0.27867 3.29069,-0.95677 4.27229,-1.44911 1.85104,-0.91959 4.91736,-3.09324 8.76896,-6.22365 5.86156,-4.756 8.19866,-6.56736 9.1616,-7.07828 0.48612,-0.26938 0.64507,-0.30652 1.26203,-0.30652 0.617,0 0.75725,0.0371 1.1873,0.27867 l 0.47677,0.28796 -2.24364,2.31295 c -10.68543,11.05401 -12.29338,12.95826 -14.37811,17.04546 -1.79491,3.52986 -3.03827,7.25475 -3.50571,10.49663 -0.28981,2.07148 -0.11211,6.01003 0.37392,7.89573 0.35526,1.39333 0.99094,2.93533 1.57057,3.76207 0.82269,1.18898 2.08473,2.74025 2.21562,2.74025 0.36459,0 2.2343,-1.46767 2.66435,-2.09004 0.17763,-0.2508 0.39265,-0.65021 0.47676,-0.88245 0.22437,-0.62238 0.26176,-1.99714 0.0935,-3.65989 -0.19629,-1.91355 -0.19629,-4.77458 -0.009,-5.87069 0.18698,-1.06823 0.7666,-3.20474 1.29948,-4.72813 0.98162,-2.86105 2.15954,-5.16473 4.21619,-8.26728 2.08473,-3.13971 5.83353,-7.89569 7.89953,-10.02289 0.83203,-0.8546 2.57089,-2.26653 2.67373,-2.17366 0.0373,0.0465 -0.77596,2.05289 -1.53315,3.7435 -0.52357,1.17971 -1.66408,3.43696 -2.68307,5.29478 -1.82298,3.32547 -2.49605,4.80245 -2.72043,5.96357 -0.36458,1.90426 -0.54221,4.37516 -0.54221,7.55201 0,2.78672 0.0185,3.25118 0.20563,4.45874 0.24308,1.51413 0.68245,3.63204 0.96294,4.57952 0.64501,2.19223 2.15017,4.57021 4.09466,6.47447 1.96322,1.93214 3.74879,2.83318 6.82447,3.45554 1.04699,0.20437 1.31814,0.21365 4.35643,0.12998 2.84196,-0.0837 3.74879,-0.30652 7.57232,-1.82065 2.19695,-0.87318 3.23462,-1.23545 4.58082,-1.60701 3.72074,-1.0218 6.57206,-1.29118 8.75961,-0.82673 0.99096,0.21366 1.00028,0.21366 1.35555,0.0371 0.1963,-0.10223 1.02833,-0.39944 1.84165,-0.65953 0.8227,-0.26009 1.82298,-0.65022 2.2343,-0.87316 2.70173,-1.43052 8.04915,-6.46519 9.13355,-8.61097 0.84136,-1.67203 1.47709,-5.07183 1.37424,-7.3941 -0.13089,-2.86103 -0.98159,-5.36908 -2.89803,-8.53665 -1.20597,-2.00643 -2.2063,-3.20474 -4.73039,-5.71278 -2.24364,-2.22938 -3.95444,-3.74349 -8.56327,-7.61702 -5.72135,-4.79316 -7.75934,-6.6324 -7.6939,-6.94823 0.019,-0.093 0.10293,-0.14863 0.21502,-0.12998 0.34588,0.0651 2.33715,1.39336 7.54434,5.04398 5.38475,3.77133 7.61905,5.13684 9.82534,6.02861 4.95471,1.97854 10.11514,3.00965 14.38739,2.85172 2.45871,-0.0837 4.1695,-0.48304 6.10466,-1.42124 1.11246,-0.53874 3.01955,-1.7835 4.39381,-2.87959 1.34621,-1.06825 3.81419,-3.52055 4.42187,-4.38445 1.22465,-1.75562 2.08472,-5.1833 1.95383,-7.78422 -0.0748,-1.42123 -0.31781,-2.48949 -1.17791,-5.29478 -0.86943,-2.83316 -1.44905,-4.94178 -1.61728,-5.84282 -0.19636,-1.07754 -0.14957,-4.3287 0.10293,-6.40946 0.26175,-2.18293 0.35521,-5.38765 0.20563,-6.68813 -0.23368,-1.99714 -0.80396,-4.07789 -1.55183,-5.68491 -1.25269,-2.69382 -4.18818,-5.50842 -7.19839,-6.91105 -1.77624,-0.81744 -4.39386,-1.43981 -7.40409,-1.76492 -1.57055,-0.15793 -4.91736,-0.0651 -6.33829,0.18577 -2.28107,0.39944 -5.92703,1.43981 -6.68423,1.89497 -1.00966,0.61308 -3.52444,2.94464 -9.06815,8.36945 -2.2343,2.19222 -4.84254,4.71885 -5.79608,5.6106 -1.57056,1.47696 -2.64567,2.35014 -2.75786,2.23867 -0.12153,-0.12999 1.69208,-2.87962 6.17007,-9.37268 6.22613,-9.01968 7.13294,-10.55238 8.09588,-13.62705 1.4116,-4.54234 0.0654,-10.68243 -3.35615,-15.35482 -1.11251,-1.51413 -2.58022,-2.68454 -4.693,-3.75281 -1.80426,-0.91031 -3.59918,-1.46765 -5.70262,-1.77419 -0.95355,-0.13933 -5.16973,-0.2601 -6.07655,-0.17649 z"
|
||||
id="path1-1"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00931876" /><path
|
||||
d="m 324.26695,283.12908 c -0.83436,0.0787 -3.6899,0.56207 -5.58184,0.93679 -1.36902,0.27198 -1.72154,0.3566 -2.36787,0.58021 -0.40542,0.13298 -0.49356,0.14506 -0.72272,0.0846 -0.34079,-0.0907 -1.83319,-0.17527 -3.84264,-0.22362 -3.53711,-0.0907 -5.34681,0.32032 -7.25638,1.63185 -1.32789,0.91866 -2.35026,2.04887 -3.308,3.66862 -0.57581,0.97307 -0.72855,1.83734 -0.61104,3.5538 0.094,1.35986 0.29964,2.19996 0.94596,3.87412 1.27502,3.27577 2.96718,5.63893 7.58541,10.57676 3.36087,3.60215 4.46548,4.87741 4.46548,5.17356 0,0.13297 -0.0236,0.14505 -0.32315,0.14505 -0.41716,0 -0.61108,-0.0846 -1.33966,-0.59231 -0.84606,-0.58625 -1.8273,-1.37195 -3.684,-2.9494 -2.70866,-2.29666 -3.10232,-2.62303 -4.10706,-3.42687 -1.60405,-1.26922 -2.87318,-2.12139 -3.74863,-2.51425 -1.49828,-0.67086 -3.96605,-1.06372 -5.78162,-0.91867 -2.12109,0.17527 -3.73103,0.73132 -5.34094,1.84337 -1.56877,1.09396 -4.0718,3.55984 -4.41259,4.35764 -0.22915,0.53185 -0.36429,1.64394 -0.47003,3.83181 -0.0881,1.75272 -0.0295,2.87083 0.22915,4.59939 l 0.15864,1.05768 -0.35842,1.35985 c -0.55818,2.0912 -0.75797,3.56589 -0.82846,5.923 -0.0647,2.35711 0.15274,3.79555 0.74619,5.0285 0.76971,1.58348 3.02595,4.24885 4.67113,5.50597 0.97534,0.74943 2.35613,1.26316 4.02479,1.49887 0.87545,0.12693 2.73803,0.10877 3.3491,-0.0302 0.81083,-0.1813 2.06822,-0.62251 2.68516,-0.94285 1.16338,-0.59832 3.09058,-2.01259 5.51133,-4.04938 3.68402,-3.09445 5.15289,-4.273 5.75811,-4.60543 0.30552,-0.17527 0.40543,-0.19943 0.79319,-0.19943 0.38779,0 0.47593,0.0241 0.74622,0.18132 l 0.29965,0.18735 -1.41013,1.5049 c -6.71585,7.19222 -7.72645,8.43121 -9.03671,11.09052 -1.12811,2.29668 -1.90957,4.72026 -2.20336,6.82956 -0.18214,1.34779 -0.0705,3.91039 0.23501,5.1373 0.22329,0.90657 0.62281,1.90985 0.98711,2.44777 0.51707,0.7736 1.31027,1.78292 1.39253,1.78292 0.22915,0 1.40427,-0.95492 1.67456,-1.35986 0.11164,-0.16318 0.24678,-0.42306 0.29964,-0.57417 0.14102,-0.40495 0.16452,-1.29942 0.0588,-2.38128 -0.12337,-1.24503 -0.12337,-3.10655 -0.006,-3.81973 0.11752,-0.69503 0.48181,-2.08513 0.81673,-3.07632 0.61695,-1.86152 1.35728,-3.36039 2.6499,-5.37905 1.31026,-2.04283 3.6664,-5.13728 4.96489,-6.52133 0.52293,-0.55603 1.61581,-1.47469 1.68045,-1.41427 0.0234,0.0302 -0.4877,1.3357 -0.96359,2.43569 -0.32907,0.76756 -1.04589,2.23623 -1.68633,3.44501 -1.14575,2.16368 -1.56877,3.12468 -1.7098,3.88015 -0.22914,1.23899 -0.34078,2.84667 -0.34078,4.91367 0,1.81315 0.0116,2.11536 0.12924,2.90105 0.15278,0.98516 0.42892,2.36316 0.60521,2.97963 0.40539,1.42635 1.35139,2.97357 2.57351,4.21257 1.2339,1.25713 2.35614,1.84339 4.28921,2.24832 0.65804,0.13298 0.82846,0.13901 2.73804,0.0846 1.78619,-0.0544 2.35613,-0.19944 4.75924,-1.18459 1.38079,-0.56813 2.03297,-0.80384 2.87906,-1.0456 2.33851,-0.66482 4.13057,-0.84009 5.50546,-0.5379 0.62282,0.13902 0.62868,0.13902 0.85197,0.0241 0.12337,-0.0665 0.64631,-0.25989 1.15748,-0.42912 0.51708,-0.16923 1.14576,-0.42306 1.40427,-0.56811 1.69805,-0.93077 5.05893,-4.20654 5.74048,-5.60268 0.5288,-1.08789 0.92836,-3.29995 0.86372,-4.81092 -0.0823,-1.8615 -0.61694,-3.49335 -1.82143,-5.55431 -0.75796,-1.30547 -1.38667,-2.08515 -2.97307,-3.71698 -1.41014,-1.45053 -2.48538,-2.43568 -5.38205,-4.95597 -3.5959,-3.11863 -4.87679,-4.31532 -4.83566,-4.52081 0.012,-0.0606 0.0647,-0.0967 0.13515,-0.0846 0.21738,0.0424 1.4689,0.90657 4.74165,3.28183 3.38434,2.45378 4.7886,3.34224 6.17527,3.92248 3.11406,1.28731 6.35741,1.9582 9.04254,1.85544 1.54531,-0.0544 2.62055,-0.31428 3.83681,-0.92471 0.69918,-0.35054 1.8978,-1.16042 2.76153,-1.87359 0.84609,-0.69505 2.39723,-2.29063 2.77916,-2.85272 0.7697,-1.14228 1.31026,-3.37248 1.22799,-5.06474 -0.047,-0.92472 -0.19974,-1.61977 -0.74032,-3.44502 -0.54644,-1.84337 -0.91073,-3.21533 -1.01647,-3.80159 -0.12341,-0.70109 -0.094,-2.81644 0.0647,-4.17027 0.16452,-1.42031 0.22326,-3.50544 0.12924,-4.35159 -0.14687,-1.29942 -0.50529,-2.65325 -0.97533,-3.69885 -0.78732,-1.75271 -2.63229,-3.58402 -4.52422,-4.49663 -1.11637,-0.53186 -2.76156,-0.9368 -4.6535,-1.14832 -0.9871,-0.10275 -3.09059,-0.0424 -3.98365,0.12086 -1.43366,0.2599 -3.72516,0.93681 -4.20107,1.23295 -0.63457,0.3989 -2.21512,1.91592 -5.69937,5.44552 -1.40427,1.42636 -3.04356,3.0703 -3.64286,3.65051 -0.98711,0.96097 -1.66282,1.5291 -1.73333,1.45657 -0.0764,-0.0846 1.06348,-1.8736 3.87792,-6.09827 3.91315,-5.86859 4.48308,-6.86583 5.08829,-8.86635 0.8872,-2.95544 0.0411,-6.95045 -2.10935,-9.9905 -0.69922,-0.98516 -1.62168,-1.74668 -2.94957,-2.44175 -1.13399,-0.59228 -2.26211,-0.95492 -3.58413,-1.15436 -0.59931,-0.0907 -3.2492,-0.16924 -3.81914,-0.11483 z"
|
||||
id="path1-1-7"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00595914" /><path
|
||||
d="m 166.59227,332.97105 c -4.12429,0.42662 -8.02317,1.5205 -12.83475,3.62077 l -1.10432,0.4813 -1.82543,-0.86416 c -4.62007,-2.20966 -8.27101,-3.06288 -12.59815,-2.94255 -2.32129,0.0656 -3.39176,0.21877 -5.27361,0.79853 -6.5131,1.97994 -11.32468,7.43841 -12.77834,14.50492 -1.09306,5.25064 -0.38311,11.54049 1.78042,15.98166 1.83677,3.75203 4.57499,6.79303 12.23748,13.62981 3.52702,3.15038 8.64287,8.10569 10.52472,10.18408 1.88177,2.10025 3.4481,3.98173 3.4481,4.17864 0,0.16407 -0.45069,0.63444 -0.60853,0.63444 -0.0563,0 -0.67604,-0.60163 -1.39724,-1.34547 -15.06588,-15.45661 -24.88064,-22.01991 -35.1236,-23.5076 -0.68745,-0.0985 -2.14102,-0.1422 -4.56374,-0.1422 -3.84253,0.0109 -4.92426,0.10938 -7.944252,0.76572 -8.237179,1.78303 -14.479919,6.60706 -16.485689,12.74376 -0.61971,1.90335 -0.75496,2.78941 -0.74371,5.14126 0,1.88148 0.0453,2.29715 0.31552,3.55512 0.56344,2.60345 1.63392,5.31628 3.15516,7.97443 0.61978,1.08295 0.61978,1.09388 0.43952,1.47674 -1.81426,4.14583 -2.91856,7.76658 -3.42567,11.33266 -0.2141,1.45486 -0.18027,4.80214 0.0563,6.06012 0.66479,3.52231 2.3438,6.26796 5.03694,8.21511 4.10171,2.96443 10.49088,3.83951 17.826601,2.45029 8.69921,-1.65182 21.45505,-7.90882 31.46141,-15.45662 5.4877,-4.14582 10.08527,-8.7292 12.39531,-12.3609 0.41686,-0.65633 0.67604,-0.82042 0.80004,-0.50319 0.15775,0.38286 -2.77206,3.87235 -5.58913,6.66176 -2.36637,2.34091 -4.15805,3.93798 -8.56403,7.61344 -1.82543,1.52051 -3.95521,3.32541 -4.73275,4.00362 -8.38368,7.30718 -11.56135,12.63435 -13.01501,21.81209 -0.29294,1.82677 -0.34927,5.15214 -0.12393,6.67266 0.5747,3.76301 1.84802,6.45398 4.11297,8.65264 1.94944,1.89241 4.19188,3.01914 7.21179,3.6098 1.44233,0.28442 4.48483,0.3938 6.26525,0.21885 3.39176,-0.33911 7.66249,-1.37836 11.1895,-2.73471 0.76629,-0.29538 0.94655,-0.28442 1.52125,0.0656 0.83387,0.51414 2.91849,1.57522 3.85378,1.96901 3.32418,1.40019 5.88215,1.99085 8.95839,2.07841 1.65643,0.044 2.18612,0.0216 3.32418,-0.16408 8.23718,-1.3674 13.97282,-7.91972 15.42647,-17.63342 0.54087,-3.56607 0.49578,-7.97443 -0.11267,-11.09198 -0.10143,-0.56885 0.10142,-0.51415 1.02539,0.27346 6.24274,5.30535 11.43744,9.37459 16.85755,13.18124 5.97223,4.21151 10.27679,6.92431 14.90812,9.38556 1.90434,1.01734 5.08202,2.58159 5.22852,2.58159 0.11268,0 0.18034,-0.12034 0.94655,-1.85964 1.44233,-3.22694 2.23112,-6.18042 2.23112,-8.39004 0,-0.85325 -0.16901,-2.06744 -0.32677,-2.30813 -0.0453,-0.0763 -0.66479,-0.22973 -1.38599,-0.35006 -10.26554,-1.67365 -20.51974,-7.02273 -32.14877,-16.7474 -2.58047,-2.15492 -3.93271,-3.36912 -3.97779,-3.56602 -0.0454,-0.18596 0.10143,-0.12033 1.48749,0.66723 7.15538,4.12403 16.1701,5.75384 22.91995,4.16776 2.71565,-0.63448 5.09327,-1.89241 6.83986,-3.59892 1.84802,-1.8049 2.97491,-3.92703 3.57211,-6.73831 0.28168,-1.3783 0.39443,-4.37555 0.20284,-6.03825 -0.3606,-3.28166 -1.35224,-7.05555 -2.76073,-10.54505 -0.21417,-0.53601 -0.39444,-1.07201 -0.39444,-1.19233 0,-0.13128 0.2141,-0.56883 0.48453,-0.98451 1.96069,-3.10663 3.29042,-6.43204 3.74112,-9.35272 0.1465,-0.95167 0.18033,-1.67364 0.13525,-2.95348 -0.0902,-2.3628 -0.42819,-3.74109 -1.43107,-5.7429 -4.13555,-8.29165 -16.74489,-12.40465 -30.80787,-10.05281 -4.91301,0.82041 -9.9951,3.06289 -15.61798,6.89147 -3.92146,2.66909 -7.29072,5.49131 -12.23748,10.23877 -1.80301,1.73929 -3.31293,3.1504 -3.35801,3.1504 -0.13526,0 0.3606,-0.62352 1.78043,-2.24247 2.20861,-2.505 3.56077,-3.89423 9.25132,-9.46211 5.43136,-5.30534 6.94136,-6.84772 8.50769,-8.69639 4.01155,-4.69276 6.41167,-9.36365 7.53856,-14.65806 1.64517,-7.76658 0.60845,-14.51585 -2.90724,-18.77106 -2.45654,-2.98631 -5.93847,-4.51775 -10.5473,-4.62714 -0.99155,-0.0219 -2.00577,-0.0219 -2.25362,0 z"
|
||||
id="path1-2"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.0111024" /><path
|
||||
d="m 465.56025,185.2456 c -0.9371,0.0986 -1.47259,0.23385 -2.432,0.62118 -1.53059,0.61754 -3.04333,1.57124 -4.03846,2.55052 -0.5444,0.52983 -1.4815,1.67354 -1.80279,2.19242 -0.22312,0.36175 -0.33468,0.90619 -0.51317,2.52859 -0.0937,0.82946 -0.13387,1.2643 -0.33915,3.59921 -0.19634,2.21435 -0.33021,3.3142 -0.41946,3.44212 -0.0714,0.106 -0.22757,-0.82218 -0.67382,-3.97194 -0.63812,-4.51274 -0.80322,-5.28374 -1.38334,-6.39822 -0.8657,-1.65162 -2.88269,-3.02554 -5.42178,-3.69057 -1.27179,-0.33251 -2.30706,-0.33982 -3.6904,-0.0292 -1.20484,0.27404 -2.23118,0.72349 -3.37355,1.49083 -1.02635,0.68697 -1.602,1.19121 -2.93624,2.56148 -1.25394,1.28623 -1.96345,2.07549 -2.22673,2.47378 -0.0893,0.13886 -0.1785,0.21559 -0.30791,0.27041 -0.22311,0.095 -0.3079,0.1498 -1.41011,0.88792 -1.22716,0.82581 -1.75372,1.20583 -2.2535,1.63701 -1.03526,0.89158 -1.57968,1.62238 -1.93221,2.60532 -0.23651,0.65772 -0.29452,1.01947 -0.29452,1.827 0.005,0.98659 0.13834,1.71739 0.40607,2.15224 0.22759,0.37636 1.04867,1.17293 1.61093,1.56756 0.87463,0.6139 2.75329,1.42144 4.13216,1.77955 1.81173,0.46771 3.55652,0.69789 7.45663,0.98655 3.1549,0.23386 4.33744,0.35079 4.65873,0.46043 l 0.15172,0.0512 -0.15172,0.13155 c -0.18742,0.15714 -0.415,0.21559 -1.15576,0.28502 -0.7943,0.0767 -1.86527,0.12425 -3.88226,0.16807 -3.71271,0.0804 -5.30578,0.18272 -6.47045,0.42022 -1.55737,0.31792 -3.56545,1.43604 -4.73013,2.63091 -1.22269,1.26066 -1.6957,2.38609 -1.94114,4.62235 -0.0893,0.78928 -0.0893,1.53834 0,1.77588 0.12049,0.33616 0.78985,1.15466 1.75372,2.14489 0.7006,0.7162 1.2227,1.16564 2.03039,1.73932 l 0.76753,0.54811 0.39714,0.69793 c 0.21866,0.38368 0.49534,0.84041 0.61582,1.01582 0.72737,1.0414 1.95452,2.36051 2.905,3.1242 0.89694,0.71983 1.52168,1.01581 2.67297,1.2643 1.55737,0.3398 3.95367,0.48599 4.9934,0.30326 1.19145,-0.2046 2.68635,-0.91716 3.79749,-1.80509 0.49978,-0.39828 1.01742,-1.00851 1.44134,-1.70644 0.52211,-0.85867 0.9371,-2.26182 1.51721,-5.1741 0.42838,-2.12665 0.69613,-3.29958 0.87016,-3.75634 0.17404,-0.45676 0.43286,-0.66868 0.91033,-0.74178 l 0.16956,-0.0254 -0.0268,0.30694 c -0.0357,0.40192 -0.18741,3.10593 -0.25434,4.52734 -0.058,1.20218 -0.0312,3.1242 0.0491,3.69057 0.19635,1.40679 0.81215,3.084 1.67339,4.56024 0.62919,1.07427 1.16021,1.68085 2.22672,2.54685 0.83001,0.67599 1.31195,0.98292 1.99024,1.26063 0.52655,0.21559 0.94155,0.32523 1.83849,0.47502 0.78092,0.13521 0.80323,0.13156 0.88355,-0.10588 0.0223,-0.0731 0.0848,-0.32156 0.13833,-0.55178 0.12496,-0.55542 0.0982,-0.76369 -0.14726,-1.16928 -0.16956,-0.28502 -0.24989,-0.36542 -1.02634,-0.99755 -1.36103,-1.11448 -1.72694,-1.50547 -2.26689,-2.41899 -1.24054,-2.09376 -1.70909,-3.80747 -1.94114,-7.08881 -0.11601,-1.6041 -0.0893,-2.96707 0.067,-3.54439 0.0893,-0.3435 0.0937,-0.34715 0.18741,-0.12792 0.46409,1.10352 0.79877,2.09743 1.19146,3.56269 0.53995,1.98414 0.65151,2.22164 1.602,3.33248 1.29855,1.52007 2.29812,2.41896 3.71269,3.33615 1.24501,0.80751 2.15534,1.17656 3.42265,1.38487 1.66893,0.27403 2.90054,0.14615 4.25264,-0.44217 0.70952,-0.31057 1.13791,-0.56269 1.43689,-0.84404 0.15172,-0.14251 0.44624,-0.37637 0.65597,-0.52256 0.81661,-0.55174 1.16467,-0.97196 2.15533,-2.59069 0.70952,-1.15469 1.16468,-1.7576 1.99468,-2.63091 0.62027,-0.6504 1.14683,-1.05236 1.76264,-1.352 l 0.53102,-0.25578 0.20973,-0.32887 c 0.11603,-0.18269 0.3213,-0.48598 0.46409,-0.67599 0.415,-0.56637 0.60689,-1.04871 0.80769,-2.02432 0.18742,-0.92446 0.26329,-1.65893 0.26329,-2.5615 -0.005,-1.02677 -0.0402,-1.16928 -0.52656,-1.97315 -1.02635,-1.69184 -2.28921,-2.65285 -4.35529,-3.31788 -1.01742,-0.32521 -1.91881,-0.51521 -2.96748,-0.62482 -1.35656,-0.14252 -1.72694,-0.14983 -6.69357,-0.14983 -2.75774,0 -4.89076,-0.0145 -4.92646,-0.0329 -0.0491,-0.0254 -0.0491,-0.0365 0.005,-0.0621 0.1428,-0.0658 1.16021,-0.17174 3.94028,-0.41655 3.67253,-0.32521 4.65426,-0.4604 5.84571,-0.82215 1.91883,-0.57735 3.35571,-1.20949 4.864,-2.1376 1.70909,-1.05239 2.5614,-1.99877 3.07904,-3.42018 0.34806,-0.94275 0.60242,-2.36781 0.60242,-3.32152 -0.005,-0.76369 -0.12049,-1.15833 -0.58011,-1.91836 -0.6649,-1.09621 -1.36549,-1.73567 -2.61942,-2.40071 -0.35252,-0.18635 -1.1513,-0.61388 -1.77156,-0.95004 -1.60646,-0.86236 -2.02592,-1.20583 -3.22184,-2.6236 -0.67829,-0.8112 -1.13345,-1.28988 -1.63322,-1.74297 -1.17807,-1.05967 -2.6462,-1.78682 -4.09647,-2.02433 -0.49532,-0.0841 -1.75818,-0.12059 -2.27581,-0.0695 z"
|
||||
id="path1-3-3"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00403802" /><path
|
||||
d="m 129.33803,187.58044 c -0.9371,0.10563 -1.47259,0.25052 -2.432,0.66548 -1.53059,0.66158 -3.04333,1.6833 -4.03846,2.73242 -0.5444,0.56761 -1.4815,1.79289 -1.80279,2.34878 -0.22312,0.38755 -0.33468,0.97082 -0.51317,2.70892 -0.0937,0.88862 -0.13387,1.35447 -0.33915,3.8559 -0.19634,2.37228 -0.33021,3.55057 -0.41946,3.68761 -0.0714,0.11356 -0.22757,-0.88082 -0.67382,-4.25521 -0.63812,-4.83459 -0.80322,-5.66057 -1.38334,-6.85453 -0.8657,-1.76942 -2.88269,-3.24132 -5.42178,-3.95378 -1.27179,-0.35622 -2.30706,-0.36406 -3.6904,-0.0313 -1.20484,0.29358 -2.23118,0.77509 -3.37355,1.59715 -1.02635,0.73596 -1.602,1.27617 -2.93624,2.74416 -1.25394,1.37796 -1.96345,2.22351 -2.22673,2.65021 -0.0893,0.14876 -0.178502,0.23096 -0.307912,0.28969 -0.22311,0.10178 -0.3079,0.16049 -1.41011,0.95125 -1.22716,0.8847 -1.75372,1.29183 -2.2535,1.75376 -1.03526,0.95516 -1.57968,1.73808 -1.93221,2.79112 -0.23651,0.70463 -0.29452,1.09218 -0.29452,1.9573 0.005,1.05695 0.13834,1.83987 0.40607,2.30574 0.22759,0.4032 1.04867,1.25658 1.61093,1.67935 0.87463,0.65769 2.75329,1.52282 4.132162,1.90647 1.81173,0.50106 3.55652,0.74766 7.45663,1.05691 3.1549,0.25054 4.33744,0.3758 4.65873,0.49326 l 0.15172,0.0549 -0.15172,0.14093 c -0.18742,0.16834 -0.415,0.23096 -1.15576,0.30534 -0.7943,0.0822 -1.86527,0.13312 -3.88226,0.18006 -3.71271,0.0861 -5.30578,0.19575 -6.47045,0.45019 -1.557372,0.34059 -3.565452,1.53846 -4.730132,2.81854 -1.22269,1.35057 -1.6957,2.55627 -1.94114,4.95201 -0.0893,0.84557 -0.0893,1.64805 0,1.90253 0.12049,0.36014 0.78985,1.23701 1.75372,2.29786 0.7006,0.76728 1.2227,1.24878 2.03039,1.86337 l 0.76753,0.5872 0.39714,0.74771 c 0.21866,0.41104 0.49534,0.90034 0.61582,1.08826 0.727372,1.11567 1.954522,2.52886 2.905002,3.34702 0.89694,0.77116 1.52168,1.08825 2.67297,1.35446 1.55737,0.36404 3.95367,0.52065 4.9934,0.32489 1.19145,-0.21919 2.68635,-0.98257 3.79749,-1.93382 0.49978,-0.42669 1.01742,-1.08044 1.44134,-1.82815 0.52211,-0.9199 0.9371,-2.42312 1.51721,-5.5431 0.42838,-2.27832 0.69613,-3.5349 0.87016,-4.02424 0.17404,-0.48934 0.43286,-0.71637 0.91033,-0.79468 l 0.16956,-0.0272 -0.0268,0.32883 c -0.0357,0.43058 -0.18741,3.32744 -0.25434,4.85022 -0.058,1.28792 -0.0312,3.34701 0.0491,3.95377 0.19635,1.50712 0.81215,3.30395 1.67339,4.88547 0.62919,1.15089 1.16021,1.80073 2.22672,2.72849 0.83001,0.7242 1.31195,1.05302 1.99024,1.35054 0.52655,0.23096 0.94155,0.34842 1.83849,0.50889 0.78092,0.14486 0.80323,0.14095 0.88355,-0.11343 0.0223,-0.0783 0.0848,-0.34449 0.13833,-0.59113 0.12496,-0.59503 0.0982,-0.81815 -0.14726,-1.25267 -0.16956,-0.30535 -0.24989,-0.39148 -1.02634,-1.06869 -1.36103,-1.19397 -1.72694,-1.61284 -2.26689,-2.59151 -1.24054,-2.24309 -1.70909,-4.07901 -1.94114,-7.59437 -0.11601,-1.71851 -0.0893,-3.17868 0.067,-3.79717 0.0893,-0.368 0.0937,-0.37191 0.18741,-0.13705 0.46409,1.18222 0.79877,2.24702 1.19146,3.81678 0.53995,2.12564 0.65151,2.38008 1.602,3.57014 1.29855,1.62848 2.29812,2.59148 3.71269,3.57408 1.24501,0.8651 2.15534,1.26047 3.42265,1.48364 1.66893,0.29357 2.90054,0.15657 4.25264,-0.4737 0.70952,-0.33272 1.13791,-0.60282 1.43689,-0.90424 0.15172,-0.15267 0.44624,-0.40321 0.65597,-0.55983 0.81661,-0.59109 1.16467,-1.04128 2.15533,-2.77545 0.70952,-1.23704 1.16468,-1.88295 1.99468,-2.81854 0.62027,-0.69679 1.14683,-1.12742 1.76264,-1.44843 l 0.53102,-0.27402 0.20973,-0.35232 c 0.11603,-0.19572 0.3213,-0.52064 0.46409,-0.7242 0.415,-0.60677 0.60689,-1.12351 0.80769,-2.1687 0.18742,-0.99039 0.26329,-1.77724 0.26329,-2.74418 -0.005,-1.09999 -0.0402,-1.25267 -0.52656,-2.11387 -1.02635,-1.8125 -2.28921,-2.84205 -4.35529,-3.55451 -1.01742,-0.3484 -1.91881,-0.55195 -2.96748,-0.66938 -1.35656,-0.15268 -1.72694,-0.16051 -6.69357,-0.16051 -2.75774,0 -4.89076,-0.0155 -4.92646,-0.0353 -0.0491,-0.0272 -0.0491,-0.0391 0.005,-0.0665 0.1428,-0.0705 1.16021,-0.18399 3.94028,-0.44625 3.67253,-0.34841 4.65426,-0.49324 5.84571,-0.88079 1.91883,-0.61853 3.35571,-1.29575 4.864,-2.29005 1.70909,-1.12744 2.5614,-2.14132 3.07904,-3.6641 0.34806,-1.00999 0.60242,-2.53668 0.60242,-3.55841 -0.005,-0.81815 -0.12049,-1.24094 -0.58011,-2.05517 -0.6649,-1.17439 -1.36549,-1.85946 -2.61942,-2.57193 -0.35252,-0.19964 -1.1513,-0.65766 -1.77156,-1.01779 -1.60646,-0.92386 -2.02592,-1.29183 -3.22184,-2.81071 -0.67829,-0.86906 -1.13345,-1.38187 -1.63322,-1.86728 -1.17807,-1.13524 -2.6462,-1.91425 -4.09647,-2.1687 -0.49532,-0.0901 -1.75818,-0.12919 -2.27581,-0.0745 z"
|
||||
id="path1-3-3-3"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00417953" /><path
|
||||
d="m 181.97617,266.85651 c -0.67575,0.64029 -1.01388,1.06776 -1.53142,1.94677 -0.82591,1.402 -1.43323,3.05558 -1.61859,4.41795 -0.10501,0.74073 -0.14474,2.1965 -0.0812,2.79453 0.0449,0.41641 0.28862,0.90832 1.13586,2.28156 0.4312,0.70353 0.66429,1.06698 1.92402,3.01229 1.1934,1.84589 1.7576,2.78457 1.76538,2.93802 0.008,0.12563 -0.679,-0.50471 -2.94617,-2.69417 -3.24722,-3.13763 -3.84604,-3.63997 -4.97973,-4.16083 -1.68478,-0.76832 -4.10447,-0.62779 -6.50269,0.37974 -1.20085,0.50514 -2.01813,1.12178 -2.91522,2.19577 -0.77918,0.93815 -1.31147,1.90587 -1.74142,3.19138 -0.38776,1.15305 -0.53286,1.89258 -0.74653,3.76389 -0.20177,1.75747 -0.27852,2.79987 -0.24285,3.26893 0.0145,0.16203 -0.009,0.27552 -0.0772,0.3961 -0.11736,0.20827 -0.15058,0.30199 -0.56677,1.54057 -0.46093,1.38212 -0.64309,1.99519 -0.77308,2.63208 -0.27025,1.31807 -0.25296,2.21559 0.0684,3.19451 0.21449,0.65542 0.3892,0.97253 0.88059,1.60266 0.60431,0.7668 1.15373,1.25688 1.62856,1.43525 0.40772,0.15685 1.53713,0.2848 2.21873,0.25469 1.06028,-0.0468 3.02671,-0.54603 4.32722,-1.09559 1.70709,-0.72416 3.21702,-1.59353 6.45478,-3.71296 2.61931,-1.71416 3.6189,-2.33386 3.93789,-2.44144 l 0.15029,-0.0513 -0.0391,0.19387 c -0.0515,0.23528 -0.19464,0.41769 -0.73398,0.9172 -0.57692,0.53738 -1.38886,1.21831 -2.94579,2.46507 -2.86604,2.29471 -4.05453,3.33228 -4.82441,4.21777 -1.02926,1.18432 -1.92543,3.264 -2.11272,4.89652 -0.19279,1.71872 0.12071,2.88127 1.28889,4.77374 0.4102,0.66956 0.86603,1.25404 1.0807,1.3857 0.29919,0.18988 1.32282,0.42613 2.68218,0.61934 0.9859,0.13767 1.66933,0.17448 2.65257,0.13657 l 0.93618,-0.0338 0.73652,0.30584 c 0.40517,0.16793 0.90034,0.35798 1.10167,0.4224 1.20483,0.37532 2.97105,0.66689 4.18203,0.69137 1.14227,0.0225 1.8129,-0.12216 2.86802,-0.62038 1.42954,-0.67109 3.39989,-1.99764 4.10501,-2.76527 0.81094,-0.87594 1.551,-2.33064 1.88304,-3.69146 0.15001,-0.61124 0.18507,-1.39859 0.0932,-2.19803 -0.11263,-0.98388 -0.64069,-2.32822 -1.9575,-4.9494 -0.95783,-1.91694 -1.4614,-2.99312 -1.60274,-3.45416 -0.14127,-0.46104 -0.067,-0.782 0.26333,-1.12607 l 0.11765,-0.12184 0.16576,0.25561 c 0.21655,0.33508 1.74296,2.53621 2.55542,3.68556 0.68604,0.97289 1.87672,2.45652 2.28443,2.85018 1.01026,0.97967 2.51442,1.91816 4.08896,2.55231 1.14775,0.45998 1.9338,0.61405 3.29816,0.64862 1.06302,0.0285 1.6282,-0.0218 2.32975,-0.21281 0.5446,-0.14832 0.93714,-0.31233 1.73252,-0.73457 0.69541,-0.36398 0.71074,-0.3802 0.62928,-0.6138 -0.0268,-0.0705 -0.12909,-0.3019 -0.22718,-0.51371 -0.23993,-0.5085 -0.38765,-0.65493 -0.82719,-0.82384 -0.30658,-0.12047 -0.41856,-0.13492 -1.41286,-0.16137 -1.74681,-0.0514 -2.27202,-0.13652 -3.25188,-0.52473 -2.24814,-0.88795 -3.65889,-1.94345 -5.83794,-4.36435 -1.06726,-1.18192 -1.87572,-2.26149 -2.10432,-2.80592 -0.13894,-0.32171 -0.1378,-0.32718 0.0693,-0.21249 1.0359,0.58207 1.90353,1.15641 3.10353,2.06365 1.63136,1.22361 1.86349,1.34186 3.28575,1.63722 1.94456,0.40544 3.27637,0.50592 4.94514,0.37119 1.46891,-0.11838 2.40822,-0.37767 3.52998,-0.97701 1.47709,-0.78951 2.36624,-1.62971 3.0698,-2.90161 0.36807,-0.66889 0.55097,-1.12316 0.6145,-1.52243 0.0324,-0.20242 0.12132,-0.56194 0.19702,-0.8021 0.30538,-0.92146 0.32292,-1.45858 0.11565,-3.31723 -0.14562,-1.32753 -0.15518,-2.07161 -0.035,-3.25201 0.0912,-0.88041 0.25999,-1.5106 0.56112,-2.11463 l 0.26129,-0.51882 -0.0355,-0.38269 c -0.02,-0.21234 -0.0435,-0.57237 -0.047,-0.80647 -0.0188,-0.69142 -0.1617,-1.18315 -0.59777,-2.06513 -0.41543,-0.83401 -0.80282,-1.45273 -1.35208,-2.15699 -0.62876,-0.79817 -0.74312,-0.88822 -1.61417,-1.22307 -1.83539,-0.70311 -3.41173,-0.69377 -5.43857,0.0294 -0.9967,0.3579 -1.82002,0.75157 -2.71008,1.29644 -1.1518,0.70434 -1.44705,0.9213 -5.34648,3.90712 -2.16519,1.65789 -3.84869,2.92893 -3.88796,2.93596 -0.054,0.009 -0.0608,10e-4 -0.0338,-0.0515 0.0721,-0.13718 0.80639,-0.83149 2.84013,-2.69382 2.6855,-2.4616 3.37401,-3.15727 4.08931,-4.15582 1.15518,-1.60406 1.89863,-2.96113 2.51803,-4.59207 0.70142,-1.84864 0.79467,-3.09948 0.3361,-4.51978 -0.30049,-0.94486 -0.96796,-2.20974 -1.54836,-2.95392 -0.46865,-0.59288 -0.79949,-0.83139 -1.62286,-1.14813 -1.18913,-0.45564 -2.12833,-0.53342 -3.51754,-0.29852 -0.39015,0.0666 -1.27749,0.2131 -1.96905,0.3237 -1.78606,0.29293 -2.32442,0.27703 -4.12615,-0.11028 -1.02621,-0.2252 -1.67487,-0.32508 -2.34298,-0.37816 -1.5698,-0.11863 -3.16497,0.19659 -4.44811,0.88336 -0.44007,0.23218 -1.45377,0.96289 -1.82913,1.31389 z"
|
||||
id="path1-3-3-3-6"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00399432"
|
||||
inkscape:transform-center-x="323.33333"
|
||||
inkscape:transform-center-y="-3.4874273" /><path
|
||||
d="m 309.70135,218.68714 c -0.77928,0.0869 -1.22459,0.20605 -2.02242,0.54734 -1.27283,0.54414 -2.53081,1.38448 -3.35835,2.24735 -0.45271,0.46686 -1.232,1.47462 -1.49918,1.93182 -0.18554,0.31876 -0.27831,0.79848 -0.42674,2.22804 -0.0779,0.73086 -0.11133,1.11402 -0.28204,3.17139 -0.16327,1.95114 -0.2746,2.92026 -0.34882,3.03298 -0.0594,0.0934 -0.18924,-0.72446 -0.56034,-3.49982 -0.53065,-3.97634 -0.66795,-4.6557 -1.15037,-5.63771 -0.7199,-1.4553 -2.39721,-2.66591 -4.50869,-3.25189 -1.05761,-0.29299 -1.91853,-0.29943 -3.0689,-0.0257 -1.00193,0.24147 -1.85543,0.63749 -2.80541,1.31362 -0.8535,0.60532 -1.33221,1.04962 -2.44175,2.25702 -1.04276,1.13334 -1.63278,1.82879 -1.85172,2.17973 -0.0743,0.12236 -0.14844,0.18997 -0.25606,0.23827 -0.18553,0.0837 -0.25604,0.13199 -1.17263,0.78238 -1.02049,0.72765 -1.45837,1.0625 -1.87398,1.44243 -0.86092,0.7856 -1.31365,1.42953 -1.60681,2.29564 -0.19668,0.57954 -0.24492,0.89829 -0.24492,1.60983 0.004,0.86932 0.11504,1.51326 0.33768,1.89642 0.18926,0.33162 0.87207,1.03351 1.33964,1.38123 0.72733,0.54093 2.2896,1.25249 3.43626,1.56803 1.50661,0.41212 2.95756,0.61494 6.20085,0.86928 2.62358,0.20607 3.60697,0.3091 3.87415,0.40571 l 0.12617,0.0451 -0.12617,0.11591 c -0.15585,0.13846 -0.34511,0.18996 -0.96112,0.25114 -0.66053,0.0676 -1.55113,0.10948 -3.22844,0.14809 -3.08745,0.0708 -4.41223,0.161 -5.38076,0.37027 -1.29509,0.28013 -2.96499,1.26535 -3.93353,2.31819 -1.01677,1.11082 -1.41012,2.10247 -1.61423,4.07292 -0.0743,0.69547 -0.0743,1.35549 0,1.56479 0.1002,0.29621 0.65683,1.01742 1.45838,1.88994 0.58261,0.63107 1.01678,1.02709 1.68845,1.53258 l 0.63827,0.48296 0.33026,0.61497 c 0.18183,0.33808 0.41191,0.74052 0.5121,0.89508 0.60488,0.91761 1.62536,2.07993 2.41577,2.75284 0.74589,0.63427 1.26542,0.89507 2.22282,1.11402 1.29509,0.29941 3.28783,0.42823 4.15245,0.26722 0.9908,-0.18028 2.23394,-0.80815 3.15796,-1.59053 0.41561,-0.35094 0.84607,-0.88864 1.1986,-1.50361 0.43418,-0.7566 0.77928,-1.99297 1.2617,-4.55909 0.35623,-1.87386 0.57889,-2.90737 0.72361,-3.30984 0.14473,-0.40247 0.35996,-0.5892 0.75702,-0.65361 l 0.14101,-0.0224 -0.0223,0.27046 c -0.0297,0.35414 -0.15585,2.73674 -0.21151,3.9892 -0.0482,1.05928 -0.0259,2.75284 0.0408,3.25189 0.16328,1.23958 0.67537,2.71743 1.39157,4.01819 0.52323,0.94658 0.96482,1.48106 1.85172,2.24412 0.69022,0.59564 1.091,0.86609 1.65506,1.11079 0.43787,0.18996 0.78298,0.28657 1.52887,0.41856 0.6494,0.11914 0.66795,0.11592 0.73475,-0.0933 0.0185,-0.0644 0.0705,-0.28334 0.11503,-0.4862 0.10392,-0.4894 0.0817,-0.67291 -0.12246,-1.03029 -0.141,-0.25114 -0.2078,-0.32198 -0.85349,-0.87898 -1.13182,-0.98201 -1.43611,-1.32652 -1.88512,-2.13146 -1.03162,-1.84488 -1.42126,-3.35489 -1.61424,-6.2462 -0.0965,-1.41343 -0.0743,-2.61439 0.0557,-3.12309 0.0743,-0.30267 0.0779,-0.30589 0.15585,-0.11272 0.38593,0.97236 0.66425,1.84813 0.99081,3.13922 0.44901,1.7483 0.54178,1.95757 1.3322,2.93637 1.07986,1.33938 1.91109,2.13143 3.08744,2.9396 1.03533,0.71152 1.79235,1.03671 2.84623,1.22026 1.38787,0.24145 2.41206,0.12878 3.53646,-0.38961 0.59002,-0.27366 0.94627,-0.49581 1.1949,-0.74372 0.12617,-0.12557 0.37109,-0.33163 0.5455,-0.46045 0.67908,-0.48615 0.96852,-0.85642 1.79235,-2.28275 0.59002,-1.01743 0.96853,-1.54868 1.65875,-2.31818 0.51581,-0.5731 0.95369,-0.92728 1.46579,-1.1913 l 0.44159,-0.22538 0.17441,-0.28978 c 0.0965,-0.16097 0.26719,-0.42821 0.38594,-0.59564 0.34511,-0.49904 0.50468,-0.92405 0.67166,-1.7837 0.15586,-0.81457 0.21895,-1.46174 0.21895,-2.25703 -0.004,-0.90472 -0.0334,-1.03029 -0.43788,-1.73861 -0.8535,-1.49074 -1.90368,-2.33752 -3.62181,-2.9235 -0.84608,-0.28656 -1.59567,-0.45397 -2.46773,-0.55056 -1.1281,-0.12557 -1.4361,-0.13202 -5.5663,-0.13202 -2.29331,0 -4.06711,-0.0128 -4.09679,-0.029 -0.0408,-0.0224 -0.0408,-0.0322 0.004,-0.0547 0.11876,-0.058 0.96482,-0.15132 3.2767,-0.36703 3.05404,-0.28656 3.87043,-0.40568 4.86123,-0.72443 1.59568,-0.50872 2.79057,-1.06572 4.04485,-1.88352 1.42126,-0.92729 2.13004,-1.76118 2.5605,-3.01364 0.28944,-0.83069 0.50097,-2.08636 0.50097,-2.92671 -0.004,-0.67291 -0.1002,-1.02065 -0.48242,-1.69034 -0.55292,-0.96591 -1.13553,-1.52936 -2.17828,-2.11535 -0.29315,-0.1642 -0.95741,-0.54091 -1.47321,-0.83711 -1.33592,-0.75986 -1.68473,-1.0625 -2.67925,-2.31175 -0.56406,-0.71478 -0.94256,-1.13656 -1.35817,-1.53579 -0.97967,-0.93372 -2.20055,-1.57444 -3.40658,-1.78371 -0.4119,-0.0741 -1.46208,-0.10626 -1.89254,-0.0612 z"
|
||||
id="path1-3-3-2"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00345656" /><path
|
||||
d="m 434.17193,103.02813 c -0.71225,0.32793 -1.09736,0.58128 -1.74709,1.15649 -1.03665,0.91735 -1.96592,2.11115 -2.47956,3.19075 -0.28262,0.58569 -0.70482,1.78761 -0.8144,2.30569 -0.0757,0.36098 -0.0126,0.8455 0.29675,2.24905 0.15627,0.71819 0.24522,1.09238 0.73122,3.0988 0.45959,1.90326 0.65918,2.85811 0.62424,2.98847 -0.027,0.10736 -0.4078,-0.62798 -1.63417,-3.14519 -1.75608,-3.60681 -2.10037,-4.20834 -2.86754,-4.98842 -1.14163,-1.15448 -3.11488,-1.77516 -5.30345,-1.66626 -1.09607,0.055 -1.9152,0.3201 -2.9208,0.94223 -0.87487,0.54476 -1.56019,1.18945 -2.24886,2.13038 -0.6194,0.84334 -0.9338,1.41581 -1.60657,2.91123 -0.63271,1.40409 -0.97365,2.24998 -1.07091,2.65202 -0.032,0.13953 -0.0811,0.22706 -0.16798,0.30679 -0.14972,0.13788 -0.20143,0.20592 -0.86652,1.11191 -0.73935,1.01204 -1.04948,1.46776 -1.32427,1.95926 -0.56965,1.01678 -0.79652,1.77053 -0.80196,2.6849 -0.004,0.61199 0.0505,0.92971 0.2746,1.60503 0.27761,0.82381 0.58582,1.4 0.91781,1.69353 0.28408,0.25513 1.15321,0.70623 1.7065,0.88898 0.86069,0.28431 2.56757,0.46758 3.75525,0.40589 1.55973,-0.0834 3.00071,-0.34791 6.15903,-1.12806 2.55495,-0.63077 3.52074,-0.84273 3.80475,-0.83519 l 0.13395,0.003 -0.0832,0.14975 c -0.10431,0.1805 -0.26771,0.28899 -0.8331,0.54108 -0.60562,0.27221 -1.43769,0.59247 -3.01747,1.15742 -2.908,1.03966 -4.13694,1.54254 -4.99026,2.04621 -1.14094,0.67379 -2.41552,2.13484 -3.00315,3.43915 -0.61514,1.37454 -0.67613,2.43961 -0.24921,4.37405 0.14854,0.68348 0.35642,1.3099 0.49286,1.48515 0.1884,0.24957 0.94386,0.75875 1.97943,1.33439 0.75173,0.41544 1.28854,0.65456 2.08523,0.92276 l 0.7579,0.25734 0.50715,0.47965 c 0.27906,0.2636 0.62419,0.57308 0.76796,0.68822 0.86312,0.68038 2.19775,1.46212 3.15988,1.85182 0.9077,0.36705 1.48293,0.45094 2.46057,0.35719 1.32347,-0.12374 3.25536,-0.62914 4.02526,-1.05428 0.88358,-0.48318 1.86569,-1.47065 2.49625,-2.50425 0.28392,-0.46398 0.52311,-1.1099 0.66399,-1.8046 0.17378,-0.85485 0.11189,-2.13698 -0.2385,-4.72444 -0.25212,-1.89068 -0.36632,-2.94172 -0.35573,-3.36929 0.0106,-0.42757 0.15606,-0.67259 0.51262,-0.85878 l 0.12678,-0.0657 0.064,0.26371 c 0.0833,0.34547 0.71408,2.64653 1.05574,3.85278 0.2879,1.02054 0.84249,2.62088 1.06298,3.07352 0.5454,1.12506 1.49691,2.36639 2.58636,3.37536 0.79474,0.7336 1.3822,1.10178 2.4643,1.54666 0.8427,0.34792 1.30827,0.47837 1.92069,0.53295 0.47541,0.0424 0.83339,0.0254 1.58289,-0.0843 0.65387,-0.0915 0.67046,-0.10036 0.66796,-0.31997 -0.003,-0.067 -0.0223,-0.29113 -0.044,-0.49769 -0.0555,-0.49722 -0.13441,-0.66439 -0.44074,-0.93928 -0.21293,-0.19394 -0.29864,-0.24014 -1.08691,-0.56541 -1.38351,-0.57554 -1.78083,-0.80667 -2.46052,-1.42921 -1.56019,-1.42605 -2.40561,-2.73647 -3.49945,-5.41983 -0.53678,-1.3111 -0.89398,-2.45792 -0.93082,-2.98168 -0.0248,-0.31066 -0.0224,-0.31485 0.11241,-0.15607 0.67255,0.80131 1.21255,1.54485 1.92915,2.66736 0.97682,1.51789 1.13078,1.68729 2.18926,2.36731 1.44677,0.93108 2.48516,1.421 3.85619,1.81752 1.20674,0.3492 2.02765,0.4194 3.08571,0.26166 1.39327,-0.20798 2.32985,-0.6375 3.23374,-1.48366 0.47379,-0.44557 0.74194,-0.76863 0.89983,-1.08223 0.0802,-0.15892 0.24774,-0.43163 0.3727,-0.60883 0.49139,-0.6753 0.64948,-1.11789 0.98212,-2.7311 0.23953,-1.15148 0.43144,-1.77491 0.84416,-2.72265 0.30904,-0.70639 0.61308,-1.18046 1.01595,-1.59234 l 0.34813,-0.353 0.0743,-0.32997 c 0.0409,-0.18317 0.11872,-0.49057 0.17869,-0.68688 0.17036,-0.58234 0.18794,-1.03598 0.0756,-1.90446 -0.10864,-0.8222 -0.2526,-1.45631 -0.50309,-2.21112 -0.28876,-0.85741 -0.35622,-0.96733 -0.96321,-1.51219 -1.2796,-1.14604 -2.54304,-1.61894 -4.35828,-1.63393 -0.89328,-0.005 -1.65744,0.0717 -2.51554,0.25473 -1.11023,0.23614 -1.40459,0.32703 -5.32456,1.62793 -2.17659,0.72233 -3.86413,1.26888 -3.8974,1.26285 -0.0458,-0.008 -0.0489,-0.0177 -0.0134,-0.0532 0.0944,-0.0925 0.86805,-0.44751 2.99432,-1.38042 2.80833,-1.23391 3.54565,-1.60411 4.38562,-2.21871 1.35423,-0.98542 2.31286,-1.89043 3.24571,-3.06167 1.05685,-1.32775 1.4669,-2.34244 1.48096,-3.66673 0.0131,-0.87958 -0.18167,-2.13796 -0.44636,-2.93554 -0.21574,-0.6374 -0.41657,-0.93714 -0.99027,-1.45235 -0.82901,-0.74259 -1.55944,-1.09386 -2.73369,-1.32158 -0.32994,-0.0635 -1.07905,-0.21183 -1.66189,-0.33049 -1.50726,-0.3004 -1.93364,-0.47777 -3.27101,-1.35019 -0.76049,-0.50074 -1.25257,-0.78183 -1.77278,-1.02983 -1.2239,-0.57763 -2.58444,-0.80119 -3.795,-0.61995 -0.41428,0.0594 -1.42113,0.35967 -1.81549,0.53802 z"
|
||||
id="path1-3-3-2-0"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00345656" /><path
|
||||
d="m 99.090959,92.821662 c -0.71225,0.32793 -1.09736,0.58128 -1.74709,1.15649 -1.03665,0.91735 -1.96592,2.11115 -2.47956,3.19075 -0.28262,0.58569 -0.70482,1.78761 -0.8144,2.30569 -0.0757,0.36098 -0.0126,0.845498 0.29675,2.249048 0.15627,0.71819 0.24522,1.09238 0.73122,3.0988 0.45959,1.90326 0.65918,2.85811 0.62424,2.98847 -0.027,0.10736 -0.4078,-0.62798 -1.63417,-3.14519 -1.75608,-3.60681 -2.10037,-4.20834 -2.86754,-4.988418 -1.14163,-1.15448 -3.11488,-1.77516 -5.30345,-1.66626 -1.09607,0.055 -1.9152,0.3201 -2.9208,0.94223 -0.87487,0.54476 -1.56019,1.189448 -2.24886,2.130378 -0.6194,0.84334 -0.9338,1.41581 -1.60657,2.91123 -0.63271,1.40409 -0.97365,2.24998 -1.07091,2.65202 -0.032,0.13953 -0.0811,0.22706 -0.16798,0.30679 -0.14972,0.13788 -0.20143,0.20592 -0.86652,1.11191 -0.73935,1.01204 -1.04948,1.46776 -1.32427,1.95926 -0.56965,1.01678 -0.79652,1.77053 -0.80196,2.6849 -0.004,0.61199 0.0505,0.92971 0.2746,1.60503 0.27761,0.82381 0.58582,1.4 0.91781,1.69353 0.28408,0.25513 1.15321,0.70623 1.7065,0.88898 0.86069,0.28431 2.56757,0.46758 3.75525,0.40589 1.55973,-0.0834 3.00071,-0.34791 6.15903,-1.12806 2.55495,-0.63077 3.52074,-0.84273 3.80475,-0.83519 l 0.13395,0.003 -0.0832,0.14975 c -0.10431,0.1805 -0.26771,0.28899 -0.8331,0.54108 -0.60562,0.27221 -1.43769,0.59247 -3.01747,1.15742 -2.908,1.03966 -4.13694,1.54254 -4.99026,2.04621 -1.14094,0.67379 -2.41552,2.13484 -3.00315,3.43915 -0.61514,1.37454 -0.67613,2.43961 -0.24921,4.37405 0.14854,0.68348 0.35642,1.3099 0.49286,1.48515 0.1884,0.24957 0.94386,0.75875 1.97943,1.33439 0.75173,0.41544 1.28854,0.65456 2.08523,0.92276 l 0.7579,0.25734 0.50715,0.47965 c 0.27906,0.2636 0.62419,0.57308 0.76796,0.68822 0.86312,0.68038 2.19775,1.46212 3.15988,1.85182 0.9077,0.36705 1.48293,0.45094 2.46057,0.35719 1.32347,-0.12374 3.25536,-0.62914 4.02526,-1.05428 0.88358,-0.48318 1.86569,-1.47065 2.49625,-2.50425 0.28392,-0.46398 0.52311,-1.1099 0.66399,-1.8046 0.17378,-0.85485 0.11189,-2.13698 -0.2385,-4.72444 -0.25212,-1.89068 -0.36632,-2.94172 -0.35573,-3.36929 0.0106,-0.42757 0.15606,-0.67259 0.51262,-0.85878 l 0.12678,-0.0657 0.064,0.26371 c 0.0833,0.34547 0.71408,2.64653 1.055741,3.85278 0.2879,1.02054 0.84249,2.62088 1.06298,3.07352 0.5454,1.12506 1.49691,2.36639 2.58636,3.37536 0.79474,0.7336 1.3822,1.10178 2.4643,1.54666 0.8427,0.34792 1.30827,0.47837 1.92069,0.53295 0.47541,0.0424 0.83339,0.0254 1.58289,-0.0843 0.65387,-0.0915 0.67046,-0.10036 0.66796,-0.31997 -0.003,-0.067 -0.0223,-0.29113 -0.044,-0.49769 -0.0555,-0.49722 -0.13441,-0.66439 -0.44074,-0.93928 -0.21293,-0.19394 -0.29864,-0.24014 -1.08691,-0.56541 -1.38351,-0.57554 -1.78083,-0.80667 -2.46052,-1.42921 -1.56019,-1.42605 -2.40561,-2.73647 -3.49945,-5.41983 -0.53678,-1.3111 -0.89398,-2.45792 -0.93082,-2.98168 -0.0248,-0.31066 -0.0224,-0.31485 0.11241,-0.15607 0.67255,0.80131 1.21255,1.54485 1.92915,2.66736 0.97682,1.51789 1.13078,1.68729 2.18926,2.36731 1.44677,0.93108 2.48516,1.421 3.85619,1.81752 1.20674,0.3492 2.02765,0.4194 3.08571,0.26166 1.39327,-0.20798 2.32985,-0.6375 3.23374,-1.48366 0.47379,-0.44557 0.74194,-0.76863 0.89983,-1.08223 0.0802,-0.15892 0.24774,-0.43163 0.3727,-0.60883 0.49139,-0.6753 0.64948,-1.11789 0.98212,-2.7311 0.23953,-1.15148 0.43144,-1.77491 0.84416,-2.72265 0.30904,-0.70639 0.61308,-1.18046 1.01595,-1.59234 l 0.34813,-0.353 0.0743,-0.32997 c 0.0409,-0.18317 0.11872,-0.49057 0.17869,-0.68688 0.17036,-0.58234 0.18794,-1.03598 0.0756,-1.90446 -0.10864,-0.8222 -0.2526,-1.45631 -0.50309,-2.21112 -0.28876,-0.85741 -0.35622,-0.96733 -0.96321,-1.51219 -1.2796,-1.14604 -2.54304,-1.61894 -4.35828,-1.63393 -0.89328,-0.005 -1.65744,0.0717 -2.51554,0.25473 -1.11023,0.23614 -1.40459,0.32703 -5.32456,1.62793 -2.17659,0.72233 -3.86413,1.26888 -3.8974,1.26285 -0.0458,-0.008 -0.0489,-0.0177 -0.0134,-0.0532 0.0944,-0.0925 0.86805,-0.44751 2.99432,-1.38042 2.80833,-1.23391 3.54565,-1.60411 4.38562,-2.21871 1.35423,-0.98542 2.31286,-1.89043 3.24571,-3.06167 1.05685,-1.32775 1.4669,-2.34244 1.48096,-3.66673 0.0131,-0.87958 -0.18167,-2.137958 -0.44636,-2.935538 -0.21574,-0.6374 -0.41657,-0.93714 -0.99027,-1.45235 -0.82901,-0.74259 -1.55944,-1.09386 -2.73369,-1.32158 -0.32994,-0.0635 -1.07905,-0.21183 -1.66189,-0.33049 -1.50726,-0.3004 -1.93364,-0.47777 -3.27101,-1.35019 -0.76049,-0.50074 -1.25257,-0.78183 -1.77278,-1.02983 -1.2239,-0.57763 -2.58444,-0.80119 -3.795,-0.61995 -0.41428,0.0594 -1.421131,0.35967 -1.815491,0.53802 z"
|
||||
id="path1-3-3-2-0-4"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00345656" /></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 256 KiB |
|
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 352 KiB |
|
Before Width: | Height: | Size: 21 KiB |
@@ -2,7 +2,7 @@
|
||||
|
||||
These icons are licensed under GPLv3. Please see the [script for generating icons](../../tools/README.md) and appropriatedly redirect for seasonal icons.
|
||||
|
||||
- `base_named.svg` - Named variant.
|
||||
- `base_named.svg` - Named variant (deprecated).
|
||||
- `base_small.svg`: Variant used for tiny icons (16x16, 64x64, etc).
|
||||
- `base.svg`: Variant without branding/naming.
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 37 KiB |
@@ -0,0 +1,196 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
fill="none"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg7"
|
||||
sodipodi:docname="saintpatrick2026_named.svg"
|
||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||
xml:space="preserve"
|
||||
inkscape:export-filename="dev.eden_emu.eden.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata1">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Madeline_Dev</dc:title>
|
||||
<dc:identifier>mailto:madelvidel@gmail.com</dc:identifier>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:date>2025</dc:date>
|
||||
<dc:license
|
||||
rdf:resource="https://www.gnu.org/licenses/gpl-3.0.html" />
|
||||
<dc:rights>2025 Eden Emulator Project</dc:rights>
|
||||
<dc:source>https://git.eden-emu.dev</dc:source>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs7"><linearGradient
|
||||
id="swatch14"
|
||||
inkscape:swatch="solid"><stop
|
||||
style="stop-color:#66003b;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop14" /></linearGradient><linearGradient
|
||||
id="linearGradient11"
|
||||
inkscape:collect="always"><stop
|
||||
style="stop-color:#f6d512;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop11" /><stop
|
||||
style="stop-color:#1d8e53;stop-opacity:1;"
|
||||
offset="0.99898213"
|
||||
id="stop20" /><stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="0.99898213"
|
||||
id="stop12" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient11"
|
||||
id="linearGradient12"
|
||||
x1="109.74531"
|
||||
y1="106.54533"
|
||||
x2="431.05463"
|
||||
y2="427.85461"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
spreadMethod="reflect"
|
||||
gradientTransform="matrix(1.0945321,0,0,1.0945321,-39.661525,-35.159057)" /><filter
|
||||
inkscape:label="Light Contour"
|
||||
inkscape:menu="Image Paint and Draw"
|
||||
inkscape:menu-tooltip="Uses vertical specular light to draw lines"
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter11"
|
||||
x="-0.01907517"
|
||||
y="-0.054959154"
|
||||
width="1.0379885"
|
||||
height="1.1092314"><feGaussianBlur
|
||||
in="SourceGraphic"
|
||||
stdDeviation="0.38250006"
|
||||
result="result3"
|
||||
id="feGaussianBlur9" /><feComponentTransfer
|
||||
result="result1"
|
||||
in="result3"
|
||||
id="feComponentTransfer9"><feFuncR
|
||||
type="discrete"
|
||||
tableValues="0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1"
|
||||
id="feFuncR9" /><feFuncG
|
||||
type="discrete"
|
||||
tableValues="0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1"
|
||||
id="feFuncG9" /><feFuncB
|
||||
type="discrete"
|
||||
tableValues="0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1"
|
||||
id="feFuncB9" /></feComponentTransfer><feGaussianBlur
|
||||
result="result5"
|
||||
stdDeviation="0.01"
|
||||
id="feGaussianBlur10" /><feBlend
|
||||
in2="result5"
|
||||
result="result6"
|
||||
mode="lighten"
|
||||
in="result5"
|
||||
id="feBlend10" /><feColorMatrix
|
||||
in="result6"
|
||||
type="luminanceToAlpha"
|
||||
result="result2"
|
||||
id="feColorMatrix10" /><feSpecularLighting
|
||||
surfaceScale="5"
|
||||
result="result9"
|
||||
specularExponent="20"
|
||||
in="result2"
|
||||
specularConstant="1"
|
||||
id="feSpecularLighting10"><feDistantLight
|
||||
azimuth="180"
|
||||
elevation="90"
|
||||
id="feDistantLight10" /></feSpecularLighting><feComposite
|
||||
in2="result6"
|
||||
operator="arithmetic"
|
||||
in="result9"
|
||||
k1="0.4"
|
||||
k3="0.7"
|
||||
result="result3"
|
||||
id="feComposite10"
|
||||
k2="0"
|
||||
k4="0" /><feBlend
|
||||
in2="result1"
|
||||
in="result3"
|
||||
mode="normal"
|
||||
result="result8"
|
||||
id="feBlend11" /><feComposite
|
||||
in2="SourceGraphic"
|
||||
in="result8"
|
||||
operator="in"
|
||||
result="result7"
|
||||
id="feComposite11" /></filter></defs><sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="0.6363961"
|
||||
inkscape:cx="172.06265"
|
||||
inkscape:cy="122.56518"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="849"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7"
|
||||
showguides="false" /><circle
|
||||
style="fill:url(#linearGradient12);fill-opacity:1;stroke:#e4e4e4;stroke-width:14.0448;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="path8"
|
||||
cx="256.2999"
|
||||
cy="257.2999"
|
||||
r="248.67769" /><path
|
||||
id="path15"
|
||||
style="fill:#f3ffeb;fill-opacity:1;stroke:#ffffff;stroke-width:16.9642;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.33910036;paint-order:stroke fill markers"
|
||||
d="m 306.72111,24.233031 c 0,0 -11.98397,40.08696 -18.0546,60.431848 -12.96613,9.503601 -21.49377,18.397701 -21.49377,18.397701 0,0 -23.41313,-31.029398 -45.74145,-43.934598 -22.32833,-12.905201 -52.42065,-11.242483 -52.42065,-11.242483 0,0 -12.50052,4e-4 -27.63117,5.537132 -15.13066,5.536732 -21.27107,9.227888 -21.27107,9.227888 0,0 15.35165,-0.410529 37.93799,6.766716 22.58635,7.177243 32.45374,11.484796 32.45374,11.484796 l 31.02752,-6.562453 -8.44161,11.074275 c 0,0 14.80259,8.920284 22.80648,16.917787 8.0039,7.9975 11.73088,12.50812 11.73088,12.50812 0,0 -13.92373,-5.43341 -56.68427,-1.74226 -42.76055,3.69116 -84.86368,56.39265 -84.86368,56.39265 0,0 41.22428,-15.9958 65.5649,-21.32747 24.34062,-5.33166 47.58524,-7.9983 47.58524,-7.9983 0,0 -18.41865,7.3827 -38.15428,38.3474 -19.73564,30.96468 -14.0351,80.18128 -14.0351,80.18128 0,0 31.35774,-59.05848 61.39977,-78.94969 30.04203,-19.89124 36.182,-20.50642 36.182,-20.50642 0,0 -24.1209,48.39514 -33.55015,126.11445 -9.42924,77.71931 30.26089,207.72959 30.26089,207.72959 l 47.80367,-6.97298 c 0,0 -45.61041,-42.24281 -49.55753,-151.33695 -3.94713,-109.09413 16.66479,-174.30453 16.66479,-174.30453 0,0 17.10508,1.23039 42.54213,32.81027 25.43704,31.57987 40.34713,57.41795 40.34713,57.41795 0,0 9.65024,-51.26683 -11.4011,-74.64415 -21.05135,-23.3773 -53.50637,-33.62931 -53.50637,-33.62931 0,0 13.70573,-6.66419 42.10313,-4.71609 28.39738,1.94813 87.30278,27.12897 87.30278,27.12896 0,0 -15.8158,-25.5214 -52.87463,-43.21167 -37.05881,-17.69028 -81.35597,0.29238 -81.35597,0.29238 0,0 4.13589,-15.37277 29.10021,-32.628037 24.96432,-17.25527 56.907,-34.36427 56.907,-34.36427 0,0 -26.3595,1.160335 -55.20025,12.035504 -7.176,2.7059 -14.064,6.299542 -20.36309,10.173104 l 17.40574,-51.051762 z" /><path
|
||||
d="m 364.02341,369.59545 c -1.05628,0.0923 -4.67136,0.65996 -7.06652,1.09993 -1.73317,0.31934 -2.17946,0.41869 -2.99769,0.68125 -0.51326,0.15613 -0.62485,0.17032 -0.91495,0.0993 -0.43144,-0.10644 -2.3208,-0.2058 -4.86474,-0.26256 -4.47793,-0.10645 -6.76898,0.3761 -9.18647,1.91601 -1.68109,1.07865 -2.9754,2.40567 -4.18788,4.3075 -0.72897,1.14251 -0.92234,2.15729 -0.77357,4.17266 0.11901,1.59667 0.37935,2.58307 1.19757,4.54877 1.61417,3.84622 3.75641,6.6209 9.60302,12.41863 4.25482,4.22943 5.65324,5.72676 5.65324,6.07449 0,0.15612 -0.0298,0.17031 -0.40911,0.17031 -0.52812,0 -0.77362,-0.0993 -1.69599,-0.69545 -1.0711,-0.68834 -2.31333,-1.61087 -4.66389,-3.46302 -3.42913,-2.69661 -3.92749,-3.07982 -5.19948,-4.02364 -2.0307,-1.49024 -3.6374,-2.49082 -4.74571,-2.95209 -1.8968,-0.78769 -5.02097,-1.24895 -7.31945,-1.07864 -2.68526,0.20579 -4.72343,0.85866 -6.76156,2.16438 -1.98605,1.28445 -5.15484,4.17977 -5.58628,5.11648 -0.29009,0.62448 -0.46118,1.93022 -0.59505,4.4991 -0.11158,2.05794 -0.0373,3.37077 0.29011,5.40033 l 0.20083,1.24187 -0.45376,1.59667 c -0.70663,2.45535 -0.95956,4.18686 -1.04882,6.95444 -0.0819,2.76759 0.19338,4.45651 0.94467,5.90417 0.97445,1.85925 3.83081,4.98875 5.91358,6.46479 1.23478,0.87994 2.98284,1.48315 5.09534,1.7599 1.10831,0.14903 3.4663,0.12773 4.23992,-0.0355 1.02649,-0.21289 2.61833,-0.73092 3.39936,-1.10704 1.47284,-0.70253 3.91264,-2.36308 6.97727,-4.75455 4.66392,-3.63334 6.5235,-5.01713 7.28968,-5.40744 0.3868,-0.20579 0.51327,-0.23417 1.00417,-0.23417 0.49094,0 0.60253,0.0284 0.94471,0.21289 l 0.37936,0.21999 -1.78522,1.76698 c -8.50216,8.44468 -9.78157,9.89943 -11.44034,13.02184 -1.42817,2.69662 -2.41749,5.54225 -2.78942,8.01888 -0.23059,1.5825 -0.0892,4.59135 0.29753,6.03192 0.28267,1.06444 0.78846,2.24244 1.24966,2.87403 0.6546,0.90832 1.65877,2.09341 1.76292,2.09341 0.2901,0 1.77778,-1.12122 2.11996,-1.59668 0.14134,-0.1916 0.31243,-0.49673 0.37936,-0.67415 0.17852,-0.47546 0.20827,-1.52571 0.0744,-2.79596 -0.15619,-1.46186 -0.15619,-3.64754 -0.007,-4.48491 0.14877,-0.81607 0.60996,-2.44825 1.03396,-3.61204 0.78105,-2.18569 1.71829,-3.94559 3.35473,-6.31577 1.65877,-2.39857 4.64161,-6.0319 6.28548,-7.65697 0.66203,-0.65287 2.0456,-1.73151 2.12743,-1.66056 0.0297,0.0355 -0.61742,1.5683 -1.2199,2.85984 -0.41659,0.90123 -1.32407,2.62566 -2.13486,4.04493 -1.4505,2.54049 -1.98605,3.66882 -2.16458,4.55586 -0.29009,1.45476 -0.43143,3.34239 -0.43143,5.76934 0,2.12891 0.0147,2.48374 0.16362,3.40625 0.19341,1.15672 0.54301,2.77469 0.76619,3.49851 0.51322,1.67475 1.71084,3.49141 3.25803,4.94616 1.56209,1.47606 2.98283,2.16441 5.43008,2.63985 0.83307,0.15613 1.04881,0.16322 3.46631,0.0993 2.26129,-0.0639 2.98283,-0.23417 6.02513,-1.39088 1.74807,-0.66706 2.57372,-0.94382 3.64486,-1.22767 2.96051,-0.7806 5.22924,-0.9864 6.96983,-0.63158 0.78848,0.16322 0.7959,0.16322 1.07858,0.0284 0.15619,-0.0781 0.81822,-0.30515 1.46536,-0.50385 0.6546,-0.1987 1.4505,-0.49674 1.77778,-0.66705 2.14971,-1.09285 6.40453,-4.93907 7.26737,-6.57833 0.66945,-1.27735 1.17528,-3.87462 1.09345,-5.64871 -0.10415,-2.18568 -0.78103,-4.1017 -2.3059,-6.52156 -0.95956,-1.53281 -1.7555,-2.44825 -3.76387,-4.36426 -1.78521,-1.70313 -3.14646,-2.85984 -6.8136,-5.81901 -4.55235,-3.66173 -6.17394,-5.06681 -6.12187,-5.30809 0.0151,-0.071 0.0819,-0.11354 0.17109,-0.0993 0.27521,0.0497 1.85962,1.06446 6.00286,3.85334 4.28453,2.88111 6.06231,3.92428 7.81781,4.60554 3.94235,1.51151 8.04839,2.29922 11.44773,2.17857 1.95634,-0.0639 3.31758,-0.36901 4.85734,-1.08575 0.88516,-0.41157 2.40259,-1.3625 3.49606,-2.19986 1.07115,-0.81608 3.03487,-2.68952 3.51838,-3.34949 0.97443,-1.3412 1.65877,-3.95977 1.55462,-5.94674 -0.0595,-1.08575 -0.25287,-1.90184 -0.93723,-4.04494 -0.69179,-2.16438 -1.15298,-3.77526 -1.28684,-4.4636 -0.15624,-0.82319 -0.11901,-3.30691 0.0819,-4.8965 0.20827,-1.66764 0.28263,-4.11589 0.16362,-5.10938 -0.18594,-1.52571 -0.6397,-3.1153 -1.23476,-4.34298 -0.99674,-2.05794 -3.33244,-4.20814 -5.7276,-5.27968 -1.41332,-0.62449 -3.4961,-1.09994 -5.89127,-1.34831 -1.24965,-0.12065 -3.91264,-0.0497 -5.04324,0.14192 -1.815,0.30515 -4.71601,1.09994 -5.31849,1.44766 -0.80337,0.46836 -2.80432,2.24955 -7.21533,6.39382 -1.77778,1.67474 -3.8531,3.60496 -4.61181,4.28621 -1.24966,1.12832 -2.1051,1.79538 -2.19437,1.71022 -0.0967,-0.0993 1.34635,-2.19987 4.90939,-7.16023 4.95399,-6.89057 5.67552,-8.06147 6.44171,-10.41036 1.12318,-3.47012 0.052,-8.16082 -2.67041,-11.73029 -0.8852,-1.15671 -2.05303,-2.05085 -3.73412,-2.86694 -1.43561,-0.69544 -2.86379,-1.12122 -4.53745,-1.3554 -0.75872,-0.10644 -4.11344,-0.1987 -4.83498,-0.13482 z"
|
||||
id="path1"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00726536" /><path
|
||||
d="m 83.20673,250.24331 c -1.05628,0.0923 -4.67136,0.65996 -7.06652,1.09993 -1.73317,0.31934 -2.17946,0.41869 -2.99769,0.68125 -0.51326,0.15613 -0.62485,0.17032 -0.91495,0.0993 -0.43144,-0.10644 -2.3208,-0.2058 -4.86474,-0.26256 -4.47793,-0.10645 -6.76898,0.3761 -9.18647,1.91601 -1.68109,1.07865 -2.9754,2.40567 -4.18788,4.3075 -0.72897,1.14251 -0.92234,2.15729 -0.77357,4.17266 0.11901,1.59667 0.37935,2.58307 1.19757,4.54877 1.61417,3.84622 3.75641,6.6209 9.60302,12.41863 4.25482,4.22943 5.65324,5.72676 5.65324,6.07449 0,0.15612 -0.0298,0.17031 -0.40911,0.17031 -0.52812,0 -0.77362,-0.0993 -1.69599,-0.69545 -1.0711,-0.68834 -2.31333,-1.61087 -4.66389,-3.46302 -3.42913,-2.69661 -3.92749,-3.07982 -5.19948,-4.02364 -2.0307,-1.49024 -3.6374,-2.49082 -4.74571,-2.95209 -1.8968,-0.78769 -5.02097,-1.24895 -7.31945,-1.07864 -2.68526,0.20579 -4.72343,0.85866 -6.76156,2.16438 -1.98605,1.28445 -5.15484,4.17977 -5.58628,5.11648 -0.29009,0.62448 -0.46118,1.93022 -0.59505,4.4991 -0.11158,2.05794 -0.0373,3.37077 0.29011,5.40033 l 0.20083,1.24187 -0.45376,1.59667 c -0.70663,2.45535 -0.95956,4.18686 -1.04882,6.95444 -0.0819,2.76759 0.19338,4.45651 0.94467,5.90417 0.97445,1.85925 3.83081,4.98875 5.91358,6.46479 1.23478,0.87994 2.98284,1.48315 5.09534,1.7599 1.10831,0.14903 3.4663,0.12773 4.23992,-0.0355 1.02649,-0.21289 2.61833,-0.73092 3.39936,-1.10704 1.47284,-0.70253 3.91264,-2.36308 6.97727,-4.75455 4.66392,-3.63334 6.5235,-5.01713 7.28968,-5.40744 0.3868,-0.20579 0.51327,-0.23417 1.00417,-0.23417 0.49094,0 0.60253,0.0284 0.94471,0.21289 l 0.37936,0.21999 -1.78522,1.76698 c -8.50216,8.44468 -9.78157,9.89943 -11.44034,13.02184 -1.42817,2.69662 -2.41749,5.54225 -2.78942,8.01888 -0.23059,1.5825 -0.0892,4.59135 0.29753,6.03192 0.28267,1.06444 0.78846,2.24244 1.24966,2.87403 0.6546,0.90832 1.65877,2.09341 1.76292,2.09341 0.2901,0 1.77778,-1.12122 2.11996,-1.59668 0.14134,-0.1916 0.31243,-0.49673 0.37936,-0.67415 0.17852,-0.47546 0.20827,-1.52571 0.0744,-2.79596 -0.15619,-1.46186 -0.15619,-3.64754 -0.007,-4.48491 0.14877,-0.81607 0.60996,-2.44825 1.03396,-3.61204 0.78105,-2.18569 1.71829,-3.94559 3.35473,-6.31577 1.65877,-2.39857 4.64161,-6.0319 6.28548,-7.65697 0.66203,-0.65287 2.0456,-1.73151 2.12743,-1.66056 0.0297,0.0355 -0.61742,1.5683 -1.2199,2.85984 -0.41659,0.90123 -1.32407,2.62566 -2.13486,4.04493 -1.4505,2.54049 -1.98605,3.66882 -2.16458,4.55586 -0.29009,1.45476 -0.43143,3.34239 -0.43143,5.76934 0,2.12891 0.0147,2.48374 0.16362,3.40625 0.19341,1.15672 0.54301,2.77469 0.76619,3.49851 0.51322,1.67475 1.71084,3.49141 3.25803,4.94616 1.56209,1.47606 2.98283,2.16441 5.43008,2.63985 0.83307,0.15613 1.04881,0.16322 3.46631,0.0993 2.26129,-0.0639 2.98283,-0.23417 6.02513,-1.39088 1.74807,-0.66706 2.57372,-0.94382 3.64486,-1.22767 2.96051,-0.7806 5.22924,-0.9864 6.96983,-0.63158 0.78848,0.16322 0.7959,0.16322 1.07858,0.0284 0.15619,-0.0781 0.81822,-0.30515 1.46536,-0.50385 0.6546,-0.1987 1.4505,-0.49674 1.77778,-0.66705 2.14971,-1.09285 6.40453,-4.93907 7.26737,-6.57833 0.66945,-1.27735 1.17528,-3.87462 1.09345,-5.64871 -0.10415,-2.18568 -0.78103,-4.1017 -2.3059,-6.52156 -0.95956,-1.53281 -1.7555,-2.44825 -3.76387,-4.36426 -1.78521,-1.70313 -3.14646,-2.85984 -6.8136,-5.81901 -4.55235,-3.66173 -6.17394,-5.06681 -6.12187,-5.30809 0.0151,-0.071 0.0819,-0.11354 0.17109,-0.0993 0.27521,0.0497 1.85962,1.06446 6.00286,3.85334 4.28453,2.88111 6.06231,3.92428 7.81781,4.60554 3.94235,1.51151 8.04839,2.29922 11.44773,2.17857 1.95634,-0.0639 3.31758,-0.36901 4.85734,-1.08575 0.88516,-0.41157 2.40259,-1.3625 3.49606,-2.19986 1.07115,-0.81608 3.03487,-2.68952 3.51838,-3.34949 0.97443,-1.3412 1.65877,-3.95977 1.55462,-5.94674 -0.0595,-1.08575 -0.25287,-1.90184 -0.93723,-4.04494 -0.69179,-2.16438 -1.15298,-3.77526 -1.28684,-4.4636 -0.15624,-0.82319 -0.11901,-3.30691 0.0819,-4.8965 0.20827,-1.66764 0.28263,-4.11589 0.16362,-5.10938 -0.18594,-1.52571 -0.6397,-3.1153 -1.23476,-4.34298 -0.99674,-2.05794 -3.33244,-4.20814 -5.7276,-5.27968 -1.41332,-0.62449 -3.4961,-1.09994 -5.89127,-1.34831 -1.24965,-0.12065 -3.91264,-0.0497 -5.04324,0.14192 -1.815,0.30515 -4.71601,1.09994 -5.31849,1.44766 -0.80337,0.46836 -2.80432,2.24955 -7.21533,6.39382 -1.77778,1.67474 -3.8531,3.60496 -4.61181,4.28621 -1.24966,1.12832 -2.1051,1.79538 -2.19437,1.71022 -0.0967,-0.0993 1.34635,-2.19987 4.90939,-7.16023 4.95399,-6.89057 5.67552,-8.06147 6.44171,-10.41036 1.12318,-3.47012 0.052,-8.16082 -2.67041,-11.73029 -0.8852,-1.15671 -2.05303,-2.05085 -3.73412,-2.86694 -1.43561,-0.69544 -2.86379,-1.12122 -4.53745,-1.3554 -0.75872,-0.10644 -4.11344,-0.1987 -4.83498,-0.13482 z"
|
||||
id="path1-9"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00726536" /><path
|
||||
d="m 439.21947,248.58317 c -1.32752,0.12081 -5.87092,0.86387 -8.88113,1.43979 -2.17823,0.41802 -2.73912,0.54806 -3.76747,0.89175 -0.64506,0.20437 -0.7853,0.22295 -1.1499,0.12998 -0.54223,-0.13933 -2.91676,-0.26938 -6.11395,-0.34369 -5.62782,-0.13934 -8.50719,0.49231 -11.54547,2.50804 -2.11277,1.41194 -3.73945,3.14899 -5.26329,5.63847 -0.91615,1.49553 -1.15918,2.82387 -0.97221,5.46197 0.14957,2.09002 0.47676,3.38121 1.5051,5.9543 2.02866,5.03465 4.72101,8.66669 12.06898,16.25585 5.34741,5.53628 7.10493,7.49627 7.10493,7.95145 0,0.20436 -0.0375,0.22293 -0.51416,0.22293 -0.66374,0 -0.97228,-0.12998 -2.13151,-0.91034 -1.34614,-0.90103 -2.90737,-2.10861 -5.86153,-4.53305 -4.30969,-3.52984 -4.93603,-4.03145 -6.53465,-5.26691 -2.55217,-1.95071 -4.57145,-3.26045 -5.96436,-3.86425 -2.38388,-1.03107 -6.3103,-1.63487 -9.19901,-1.41193 -3.37482,0.26938 -5.93636,1.12398 -8.49786,2.83315 -2.49604,1.68134 -6.47855,5.47127 -7.02078,6.69742 -0.36459,0.81743 -0.57961,2.52664 -0.74785,5.88927 -0.14024,2.69383 -0.0469,4.4123 0.3646,7.06898 l 0.25241,1.6256 -0.57028,2.09002 c -0.8881,3.21403 -1.20598,5.48056 -1.31815,9.10329 -0.10293,3.62275 0.24303,5.83353 1.18725,7.7285 1.22468,2.43373 4.81452,6.53023 7.43213,8.46235 1.55185,1.15183 3.7488,1.94142 6.40377,2.30368 1.39291,0.19508 4.35641,0.16719 5.32868,-0.0464 1.29009,-0.27867 3.29069,-0.95677 4.27229,-1.44911 1.85104,-0.91959 4.91736,-3.09324 8.76896,-6.22365 5.86156,-4.756 8.19866,-6.56736 9.1616,-7.07828 0.48612,-0.26938 0.64507,-0.30652 1.26203,-0.30652 0.617,0 0.75725,0.0371 1.1873,0.27867 l 0.47677,0.28796 -2.24364,2.31295 c -10.68543,11.05401 -12.29338,12.95826 -14.37811,17.04546 -1.79491,3.52986 -3.03827,7.25475 -3.50571,10.49663 -0.28981,2.07148 -0.11211,6.01003 0.37392,7.89573 0.35526,1.39333 0.99094,2.93533 1.57057,3.76207 0.82269,1.18898 2.08473,2.74025 2.21562,2.74025 0.36459,0 2.2343,-1.46767 2.66435,-2.09004 0.17763,-0.2508 0.39265,-0.65021 0.47676,-0.88245 0.22437,-0.62238 0.26176,-1.99714 0.0935,-3.65989 -0.19629,-1.91355 -0.19629,-4.77458 -0.009,-5.87069 0.18698,-1.06823 0.7666,-3.20474 1.29948,-4.72813 0.98162,-2.86105 2.15954,-5.16473 4.21619,-8.26728 2.08473,-3.13971 5.83353,-7.89569 7.89953,-10.02289 0.83203,-0.8546 2.57089,-2.26653 2.67373,-2.17366 0.0373,0.0465 -0.77596,2.05289 -1.53315,3.7435 -0.52357,1.17971 -1.66408,3.43696 -2.68307,5.29478 -1.82298,3.32547 -2.49605,4.80245 -2.72043,5.96357 -0.36458,1.90426 -0.54221,4.37516 -0.54221,7.55201 0,2.78672 0.0185,3.25118 0.20563,4.45874 0.24308,1.51413 0.68245,3.63204 0.96294,4.57952 0.64501,2.19223 2.15017,4.57021 4.09466,6.47447 1.96322,1.93214 3.74879,2.83318 6.82447,3.45554 1.04699,0.20437 1.31814,0.21365 4.35643,0.12998 2.84196,-0.0837 3.74879,-0.30652 7.57232,-1.82065 2.19695,-0.87318 3.23462,-1.23545 4.58082,-1.60701 3.72074,-1.0218 6.57206,-1.29118 8.75961,-0.82673 0.99096,0.21366 1.00028,0.21366 1.35555,0.0371 0.1963,-0.10223 1.02833,-0.39944 1.84165,-0.65953 0.8227,-0.26009 1.82298,-0.65022 2.2343,-0.87316 2.70173,-1.43052 8.04915,-6.46519 9.13355,-8.61097 0.84136,-1.67203 1.47709,-5.07183 1.37424,-7.3941 -0.13089,-2.86103 -0.98159,-5.36908 -2.89803,-8.53665 -1.20597,-2.00643 -2.2063,-3.20474 -4.73039,-5.71278 -2.24364,-2.22938 -3.95444,-3.74349 -8.56327,-7.61702 -5.72135,-4.79316 -7.75934,-6.6324 -7.6939,-6.94823 0.019,-0.093 0.10293,-0.14863 0.21502,-0.12998 0.34588,0.0651 2.33715,1.39336 7.54434,5.04398 5.38475,3.77133 7.61905,5.13684 9.82534,6.02861 4.95471,1.97854 10.11514,3.00965 14.38739,2.85172 2.45871,-0.0837 4.1695,-0.48304 6.10466,-1.42124 1.11246,-0.53874 3.01955,-1.7835 4.39381,-2.87959 1.34621,-1.06825 3.81419,-3.52055 4.42187,-4.38445 1.22465,-1.75562 2.08472,-5.1833 1.95383,-7.78422 -0.0748,-1.42123 -0.31781,-2.48949 -1.17791,-5.29478 -0.86943,-2.83316 -1.44905,-4.94178 -1.61728,-5.84282 -0.19636,-1.07754 -0.14957,-4.3287 0.10293,-6.40946 0.26175,-2.18293 0.35521,-5.38765 0.20563,-6.68813 -0.23368,-1.99714 -0.80396,-4.07789 -1.55183,-5.68491 -1.25269,-2.69382 -4.18818,-5.50842 -7.19839,-6.91105 -1.77624,-0.81744 -4.39386,-1.43981 -7.40409,-1.76492 -1.57055,-0.15793 -4.91736,-0.0651 -6.33829,0.18577 -2.28107,0.39944 -5.92703,1.43981 -6.68423,1.89497 -1.00966,0.61308 -3.52444,2.94464 -9.06815,8.36945 -2.2343,2.19222 -4.84254,4.71885 -5.79608,5.6106 -1.57056,1.47696 -2.64567,2.35014 -2.75786,2.23867 -0.12153,-0.12999 1.69208,-2.87962 6.17007,-9.37268 6.22613,-9.01968 7.13294,-10.55238 8.09588,-13.62705 1.4116,-4.54234 0.0654,-10.68243 -3.35615,-15.35482 -1.11251,-1.51413 -2.58022,-2.68454 -4.693,-3.75281 -1.80426,-0.91031 -3.59918,-1.46765 -5.70262,-1.77419 -0.95355,-0.13933 -5.16973,-0.2601 -6.07655,-0.17649 z"
|
||||
id="path1-1"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00931876" /><path
|
||||
d="m 324.26695,283.12908 c -0.83436,0.0787 -3.6899,0.56207 -5.58184,0.93679 -1.36902,0.27198 -1.72154,0.3566 -2.36787,0.58021 -0.40542,0.13298 -0.49356,0.14506 -0.72272,0.0846 -0.34079,-0.0907 -1.83319,-0.17527 -3.84264,-0.22362 -3.53711,-0.0907 -5.34681,0.32032 -7.25638,1.63185 -1.32789,0.91866 -2.35026,2.04887 -3.308,3.66862 -0.57581,0.97307 -0.72855,1.83734 -0.61104,3.5538 0.094,1.35986 0.29964,2.19996 0.94596,3.87412 1.27502,3.27577 2.96718,5.63893 7.58541,10.57676 3.36087,3.60215 4.46548,4.87741 4.46548,5.17356 0,0.13297 -0.0236,0.14505 -0.32315,0.14505 -0.41716,0 -0.61108,-0.0846 -1.33966,-0.59231 -0.84606,-0.58625 -1.8273,-1.37195 -3.684,-2.9494 -2.70866,-2.29666 -3.10232,-2.62303 -4.10706,-3.42687 -1.60405,-1.26922 -2.87318,-2.12139 -3.74863,-2.51425 -1.49828,-0.67086 -3.96605,-1.06372 -5.78162,-0.91867 -2.12109,0.17527 -3.73103,0.73132 -5.34094,1.84337 -1.56877,1.09396 -4.0718,3.55984 -4.41259,4.35764 -0.22915,0.53185 -0.36429,1.64394 -0.47003,3.83181 -0.0881,1.75272 -0.0295,2.87083 0.22915,4.59939 l 0.15864,1.05768 -0.35842,1.35985 c -0.55818,2.0912 -0.75797,3.56589 -0.82846,5.923 -0.0647,2.35711 0.15274,3.79555 0.74619,5.0285 0.76971,1.58348 3.02595,4.24885 4.67113,5.50597 0.97534,0.74943 2.35613,1.26316 4.02479,1.49887 0.87545,0.12693 2.73803,0.10877 3.3491,-0.0302 0.81083,-0.1813 2.06822,-0.62251 2.68516,-0.94285 1.16338,-0.59832 3.09058,-2.01259 5.51133,-4.04938 3.68402,-3.09445 5.15289,-4.273 5.75811,-4.60543 0.30552,-0.17527 0.40543,-0.19943 0.79319,-0.19943 0.38779,0 0.47593,0.0241 0.74622,0.18132 l 0.29965,0.18735 -1.41013,1.5049 c -6.71585,7.19222 -7.72645,8.43121 -9.03671,11.09052 -1.12811,2.29668 -1.90957,4.72026 -2.20336,6.82956 -0.18214,1.34779 -0.0705,3.91039 0.23501,5.1373 0.22329,0.90657 0.62281,1.90985 0.98711,2.44777 0.51707,0.7736 1.31027,1.78292 1.39253,1.78292 0.22915,0 1.40427,-0.95492 1.67456,-1.35986 0.11164,-0.16318 0.24678,-0.42306 0.29964,-0.57417 0.14102,-0.40495 0.16452,-1.29942 0.0588,-2.38128 -0.12337,-1.24503 -0.12337,-3.10655 -0.006,-3.81973 0.11752,-0.69503 0.48181,-2.08513 0.81673,-3.07632 0.61695,-1.86152 1.35728,-3.36039 2.6499,-5.37905 1.31026,-2.04283 3.6664,-5.13728 4.96489,-6.52133 0.52293,-0.55603 1.61581,-1.47469 1.68045,-1.41427 0.0234,0.0302 -0.4877,1.3357 -0.96359,2.43569 -0.32907,0.76756 -1.04589,2.23623 -1.68633,3.44501 -1.14575,2.16368 -1.56877,3.12468 -1.7098,3.88015 -0.22914,1.23899 -0.34078,2.84667 -0.34078,4.91367 0,1.81315 0.0116,2.11536 0.12924,2.90105 0.15278,0.98516 0.42892,2.36316 0.60521,2.97963 0.40539,1.42635 1.35139,2.97357 2.57351,4.21257 1.2339,1.25713 2.35614,1.84339 4.28921,2.24832 0.65804,0.13298 0.82846,0.13901 2.73804,0.0846 1.78619,-0.0544 2.35613,-0.19944 4.75924,-1.18459 1.38079,-0.56813 2.03297,-0.80384 2.87906,-1.0456 2.33851,-0.66482 4.13057,-0.84009 5.50546,-0.5379 0.62282,0.13902 0.62868,0.13902 0.85197,0.0241 0.12337,-0.0665 0.64631,-0.25989 1.15748,-0.42912 0.51708,-0.16923 1.14576,-0.42306 1.40427,-0.56811 1.69805,-0.93077 5.05893,-4.20654 5.74048,-5.60268 0.5288,-1.08789 0.92836,-3.29995 0.86372,-4.81092 -0.0823,-1.8615 -0.61694,-3.49335 -1.82143,-5.55431 -0.75796,-1.30547 -1.38667,-2.08515 -2.97307,-3.71698 -1.41014,-1.45053 -2.48538,-2.43568 -5.38205,-4.95597 -3.5959,-3.11863 -4.87679,-4.31532 -4.83566,-4.52081 0.012,-0.0606 0.0647,-0.0967 0.13515,-0.0846 0.21738,0.0424 1.4689,0.90657 4.74165,3.28183 3.38434,2.45378 4.7886,3.34224 6.17527,3.92248 3.11406,1.28731 6.35741,1.9582 9.04254,1.85544 1.54531,-0.0544 2.62055,-0.31428 3.83681,-0.92471 0.69918,-0.35054 1.8978,-1.16042 2.76153,-1.87359 0.84609,-0.69505 2.39723,-2.29063 2.77916,-2.85272 0.7697,-1.14228 1.31026,-3.37248 1.22799,-5.06474 -0.047,-0.92472 -0.19974,-1.61977 -0.74032,-3.44502 -0.54644,-1.84337 -0.91073,-3.21533 -1.01647,-3.80159 -0.12341,-0.70109 -0.094,-2.81644 0.0647,-4.17027 0.16452,-1.42031 0.22326,-3.50544 0.12924,-4.35159 -0.14687,-1.29942 -0.50529,-2.65325 -0.97533,-3.69885 -0.78732,-1.75271 -2.63229,-3.58402 -4.52422,-4.49663 -1.11637,-0.53186 -2.76156,-0.9368 -4.6535,-1.14832 -0.9871,-0.10275 -3.09059,-0.0424 -3.98365,0.12086 -1.43366,0.2599 -3.72516,0.93681 -4.20107,1.23295 -0.63457,0.3989 -2.21512,1.91592 -5.69937,5.44552 -1.40427,1.42636 -3.04356,3.0703 -3.64286,3.65051 -0.98711,0.96097 -1.66282,1.5291 -1.73333,1.45657 -0.0764,-0.0846 1.06348,-1.8736 3.87792,-6.09827 3.91315,-5.86859 4.48308,-6.86583 5.08829,-8.86635 0.8872,-2.95544 0.0411,-6.95045 -2.10935,-9.9905 -0.69922,-0.98516 -1.62168,-1.74668 -2.94957,-2.44175 -1.13399,-0.59228 -2.26211,-0.95492 -3.58413,-1.15436 -0.59931,-0.0907 -3.2492,-0.16924 -3.81914,-0.11483 z"
|
||||
id="path1-1-7"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00595914" /><path
|
||||
d="m 166.59227,332.97105 c -4.12429,0.42662 -8.02317,1.5205 -12.83475,3.62077 l -1.10432,0.4813 -1.82543,-0.86416 c -4.62007,-2.20966 -8.27101,-3.06288 -12.59815,-2.94255 -2.32129,0.0656 -3.39176,0.21877 -5.27361,0.79853 -6.5131,1.97994 -11.32468,7.43841 -12.77834,14.50492 -1.09306,5.25064 -0.38311,11.54049 1.78042,15.98166 1.83677,3.75203 4.57499,6.79303 12.23748,13.62981 3.52702,3.15038 8.64287,8.10569 10.52472,10.18408 1.88177,2.10025 3.4481,3.98173 3.4481,4.17864 0,0.16407 -0.45069,0.63444 -0.60853,0.63444 -0.0563,0 -0.67604,-0.60163 -1.39724,-1.34547 -15.06588,-15.45661 -24.88064,-22.01991 -35.1236,-23.5076 -0.68745,-0.0985 -2.14102,-0.1422 -4.56374,-0.1422 -3.84253,0.0109 -4.92426,0.10938 -7.944252,0.76572 -8.237179,1.78303 -14.479919,6.60706 -16.485689,12.74376 -0.61971,1.90335 -0.75496,2.78941 -0.74371,5.14126 0,1.88148 0.0453,2.29715 0.31552,3.55512 0.56344,2.60345 1.63392,5.31628 3.15516,7.97443 0.61978,1.08295 0.61978,1.09388 0.43952,1.47674 -1.81426,4.14583 -2.91856,7.76658 -3.42567,11.33266 -0.2141,1.45486 -0.18027,4.80214 0.0563,6.06012 0.66479,3.52231 2.3438,6.26796 5.03694,8.21511 4.10171,2.96443 10.49088,3.83951 17.826601,2.45029 8.69921,-1.65182 21.45505,-7.90882 31.46141,-15.45662 5.4877,-4.14582 10.08527,-8.7292 12.39531,-12.3609 0.41686,-0.65633 0.67604,-0.82042 0.80004,-0.50319 0.15775,0.38286 -2.77206,3.87235 -5.58913,6.66176 -2.36637,2.34091 -4.15805,3.93798 -8.56403,7.61344 -1.82543,1.52051 -3.95521,3.32541 -4.73275,4.00362 -8.38368,7.30718 -11.56135,12.63435 -13.01501,21.81209 -0.29294,1.82677 -0.34927,5.15214 -0.12393,6.67266 0.5747,3.76301 1.84802,6.45398 4.11297,8.65264 1.94944,1.89241 4.19188,3.01914 7.21179,3.6098 1.44233,0.28442 4.48483,0.3938 6.26525,0.21885 3.39176,-0.33911 7.66249,-1.37836 11.1895,-2.73471 0.76629,-0.29538 0.94655,-0.28442 1.52125,0.0656 0.83387,0.51414 2.91849,1.57522 3.85378,1.96901 3.32418,1.40019 5.88215,1.99085 8.95839,2.07841 1.65643,0.044 2.18612,0.0216 3.32418,-0.16408 8.23718,-1.3674 13.97282,-7.91972 15.42647,-17.63342 0.54087,-3.56607 0.49578,-7.97443 -0.11267,-11.09198 -0.10143,-0.56885 0.10142,-0.51415 1.02539,0.27346 6.24274,5.30535 11.43744,9.37459 16.85755,13.18124 5.97223,4.21151 10.27679,6.92431 14.90812,9.38556 1.90434,1.01734 5.08202,2.58159 5.22852,2.58159 0.11268,0 0.18034,-0.12034 0.94655,-1.85964 1.44233,-3.22694 2.23112,-6.18042 2.23112,-8.39004 0,-0.85325 -0.16901,-2.06744 -0.32677,-2.30813 -0.0453,-0.0763 -0.66479,-0.22973 -1.38599,-0.35006 -10.26554,-1.67365 -20.51974,-7.02273 -32.14877,-16.7474 -2.58047,-2.15492 -3.93271,-3.36912 -3.97779,-3.56602 -0.0454,-0.18596 0.10143,-0.12033 1.48749,0.66723 7.15538,4.12403 16.1701,5.75384 22.91995,4.16776 2.71565,-0.63448 5.09327,-1.89241 6.83986,-3.59892 1.84802,-1.8049 2.97491,-3.92703 3.57211,-6.73831 0.28168,-1.3783 0.39443,-4.37555 0.20284,-6.03825 -0.3606,-3.28166 -1.35224,-7.05555 -2.76073,-10.54505 -0.21417,-0.53601 -0.39444,-1.07201 -0.39444,-1.19233 0,-0.13128 0.2141,-0.56883 0.48453,-0.98451 1.96069,-3.10663 3.29042,-6.43204 3.74112,-9.35272 0.1465,-0.95167 0.18033,-1.67364 0.13525,-2.95348 -0.0902,-2.3628 -0.42819,-3.74109 -1.43107,-5.7429 -4.13555,-8.29165 -16.74489,-12.40465 -30.80787,-10.05281 -4.91301,0.82041 -9.9951,3.06289 -15.61798,6.89147 -3.92146,2.66909 -7.29072,5.49131 -12.23748,10.23877 -1.80301,1.73929 -3.31293,3.1504 -3.35801,3.1504 -0.13526,0 0.3606,-0.62352 1.78043,-2.24247 2.20861,-2.505 3.56077,-3.89423 9.25132,-9.46211 5.43136,-5.30534 6.94136,-6.84772 8.50769,-8.69639 4.01155,-4.69276 6.41167,-9.36365 7.53856,-14.65806 1.64517,-7.76658 0.60845,-14.51585 -2.90724,-18.77106 -2.45654,-2.98631 -5.93847,-4.51775 -10.5473,-4.62714 -0.99155,-0.0219 -2.00577,-0.0219 -2.25362,0 z"
|
||||
id="path1-2"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.0111024" /><path
|
||||
d="m 465.56025,185.2456 c -0.9371,0.0986 -1.47259,0.23385 -2.432,0.62118 -1.53059,0.61754 -3.04333,1.57124 -4.03846,2.55052 -0.5444,0.52983 -1.4815,1.67354 -1.80279,2.19242 -0.22312,0.36175 -0.33468,0.90619 -0.51317,2.52859 -0.0937,0.82946 -0.13387,1.2643 -0.33915,3.59921 -0.19634,2.21435 -0.33021,3.3142 -0.41946,3.44212 -0.0714,0.106 -0.22757,-0.82218 -0.67382,-3.97194 -0.63812,-4.51274 -0.80322,-5.28374 -1.38334,-6.39822 -0.8657,-1.65162 -2.88269,-3.02554 -5.42178,-3.69057 -1.27179,-0.33251 -2.30706,-0.33982 -3.6904,-0.0292 -1.20484,0.27404 -2.23118,0.72349 -3.37355,1.49083 -1.02635,0.68697 -1.602,1.19121 -2.93624,2.56148 -1.25394,1.28623 -1.96345,2.07549 -2.22673,2.47378 -0.0893,0.13886 -0.1785,0.21559 -0.30791,0.27041 -0.22311,0.095 -0.3079,0.1498 -1.41011,0.88792 -1.22716,0.82581 -1.75372,1.20583 -2.2535,1.63701 -1.03526,0.89158 -1.57968,1.62238 -1.93221,2.60532 -0.23651,0.65772 -0.29452,1.01947 -0.29452,1.827 0.005,0.98659 0.13834,1.71739 0.40607,2.15224 0.22759,0.37636 1.04867,1.17293 1.61093,1.56756 0.87463,0.6139 2.75329,1.42144 4.13216,1.77955 1.81173,0.46771 3.55652,0.69789 7.45663,0.98655 3.1549,0.23386 4.33744,0.35079 4.65873,0.46043 l 0.15172,0.0512 -0.15172,0.13155 c -0.18742,0.15714 -0.415,0.21559 -1.15576,0.28502 -0.7943,0.0767 -1.86527,0.12425 -3.88226,0.16807 -3.71271,0.0804 -5.30578,0.18272 -6.47045,0.42022 -1.55737,0.31792 -3.56545,1.43604 -4.73013,2.63091 -1.22269,1.26066 -1.6957,2.38609 -1.94114,4.62235 -0.0893,0.78928 -0.0893,1.53834 0,1.77588 0.12049,0.33616 0.78985,1.15466 1.75372,2.14489 0.7006,0.7162 1.2227,1.16564 2.03039,1.73932 l 0.76753,0.54811 0.39714,0.69793 c 0.21866,0.38368 0.49534,0.84041 0.61582,1.01582 0.72737,1.0414 1.95452,2.36051 2.905,3.1242 0.89694,0.71983 1.52168,1.01581 2.67297,1.2643 1.55737,0.3398 3.95367,0.48599 4.9934,0.30326 1.19145,-0.2046 2.68635,-0.91716 3.79749,-1.80509 0.49978,-0.39828 1.01742,-1.00851 1.44134,-1.70644 0.52211,-0.85867 0.9371,-2.26182 1.51721,-5.1741 0.42838,-2.12665 0.69613,-3.29958 0.87016,-3.75634 0.17404,-0.45676 0.43286,-0.66868 0.91033,-0.74178 l 0.16956,-0.0254 -0.0268,0.30694 c -0.0357,0.40192 -0.18741,3.10593 -0.25434,4.52734 -0.058,1.20218 -0.0312,3.1242 0.0491,3.69057 0.19635,1.40679 0.81215,3.084 1.67339,4.56024 0.62919,1.07427 1.16021,1.68085 2.22672,2.54685 0.83001,0.67599 1.31195,0.98292 1.99024,1.26063 0.52655,0.21559 0.94155,0.32523 1.83849,0.47502 0.78092,0.13521 0.80323,0.13156 0.88355,-0.10588 0.0223,-0.0731 0.0848,-0.32156 0.13833,-0.55178 0.12496,-0.55542 0.0982,-0.76369 -0.14726,-1.16928 -0.16956,-0.28502 -0.24989,-0.36542 -1.02634,-0.99755 -1.36103,-1.11448 -1.72694,-1.50547 -2.26689,-2.41899 -1.24054,-2.09376 -1.70909,-3.80747 -1.94114,-7.08881 -0.11601,-1.6041 -0.0893,-2.96707 0.067,-3.54439 0.0893,-0.3435 0.0937,-0.34715 0.18741,-0.12792 0.46409,1.10352 0.79877,2.09743 1.19146,3.56269 0.53995,1.98414 0.65151,2.22164 1.602,3.33248 1.29855,1.52007 2.29812,2.41896 3.71269,3.33615 1.24501,0.80751 2.15534,1.17656 3.42265,1.38487 1.66893,0.27403 2.90054,0.14615 4.25264,-0.44217 0.70952,-0.31057 1.13791,-0.56269 1.43689,-0.84404 0.15172,-0.14251 0.44624,-0.37637 0.65597,-0.52256 0.81661,-0.55174 1.16467,-0.97196 2.15533,-2.59069 0.70952,-1.15469 1.16468,-1.7576 1.99468,-2.63091 0.62027,-0.6504 1.14683,-1.05236 1.76264,-1.352 l 0.53102,-0.25578 0.20973,-0.32887 c 0.11603,-0.18269 0.3213,-0.48598 0.46409,-0.67599 0.415,-0.56637 0.60689,-1.04871 0.80769,-2.02432 0.18742,-0.92446 0.26329,-1.65893 0.26329,-2.5615 -0.005,-1.02677 -0.0402,-1.16928 -0.52656,-1.97315 -1.02635,-1.69184 -2.28921,-2.65285 -4.35529,-3.31788 -1.01742,-0.32521 -1.91881,-0.51521 -2.96748,-0.62482 -1.35656,-0.14252 -1.72694,-0.14983 -6.69357,-0.14983 -2.75774,0 -4.89076,-0.0145 -4.92646,-0.0329 -0.0491,-0.0254 -0.0491,-0.0365 0.005,-0.0621 0.1428,-0.0658 1.16021,-0.17174 3.94028,-0.41655 3.67253,-0.32521 4.65426,-0.4604 5.84571,-0.82215 1.91883,-0.57735 3.35571,-1.20949 4.864,-2.1376 1.70909,-1.05239 2.5614,-1.99877 3.07904,-3.42018 0.34806,-0.94275 0.60242,-2.36781 0.60242,-3.32152 -0.005,-0.76369 -0.12049,-1.15833 -0.58011,-1.91836 -0.6649,-1.09621 -1.36549,-1.73567 -2.61942,-2.40071 -0.35252,-0.18635 -1.1513,-0.61388 -1.77156,-0.95004 -1.60646,-0.86236 -2.02592,-1.20583 -3.22184,-2.6236 -0.67829,-0.8112 -1.13345,-1.28988 -1.63322,-1.74297 -1.17807,-1.05967 -2.6462,-1.78682 -4.09647,-2.02433 -0.49532,-0.0841 -1.75818,-0.12059 -2.27581,-0.0695 z"
|
||||
id="path1-3-3"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00403802" /><path
|
||||
d="m 129.33803,187.58044 c -0.9371,0.10563 -1.47259,0.25052 -2.432,0.66548 -1.53059,0.66158 -3.04333,1.6833 -4.03846,2.73242 -0.5444,0.56761 -1.4815,1.79289 -1.80279,2.34878 -0.22312,0.38755 -0.33468,0.97082 -0.51317,2.70892 -0.0937,0.88862 -0.13387,1.35447 -0.33915,3.8559 -0.19634,2.37228 -0.33021,3.55057 -0.41946,3.68761 -0.0714,0.11356 -0.22757,-0.88082 -0.67382,-4.25521 -0.63812,-4.83459 -0.80322,-5.66057 -1.38334,-6.85453 -0.8657,-1.76942 -2.88269,-3.24132 -5.42178,-3.95378 -1.27179,-0.35622 -2.30706,-0.36406 -3.6904,-0.0313 -1.20484,0.29358 -2.23118,0.77509 -3.37355,1.59715 -1.02635,0.73596 -1.602,1.27617 -2.93624,2.74416 -1.25394,1.37796 -1.96345,2.22351 -2.22673,2.65021 -0.0893,0.14876 -0.178502,0.23096 -0.307912,0.28969 -0.22311,0.10178 -0.3079,0.16049 -1.41011,0.95125 -1.22716,0.8847 -1.75372,1.29183 -2.2535,1.75376 -1.03526,0.95516 -1.57968,1.73808 -1.93221,2.79112 -0.23651,0.70463 -0.29452,1.09218 -0.29452,1.9573 0.005,1.05695 0.13834,1.83987 0.40607,2.30574 0.22759,0.4032 1.04867,1.25658 1.61093,1.67935 0.87463,0.65769 2.75329,1.52282 4.132162,1.90647 1.81173,0.50106 3.55652,0.74766 7.45663,1.05691 3.1549,0.25054 4.33744,0.3758 4.65873,0.49326 l 0.15172,0.0549 -0.15172,0.14093 c -0.18742,0.16834 -0.415,0.23096 -1.15576,0.30534 -0.7943,0.0822 -1.86527,0.13312 -3.88226,0.18006 -3.71271,0.0861 -5.30578,0.19575 -6.47045,0.45019 -1.557372,0.34059 -3.565452,1.53846 -4.730132,2.81854 -1.22269,1.35057 -1.6957,2.55627 -1.94114,4.95201 -0.0893,0.84557 -0.0893,1.64805 0,1.90253 0.12049,0.36014 0.78985,1.23701 1.75372,2.29786 0.7006,0.76728 1.2227,1.24878 2.03039,1.86337 l 0.76753,0.5872 0.39714,0.74771 c 0.21866,0.41104 0.49534,0.90034 0.61582,1.08826 0.727372,1.11567 1.954522,2.52886 2.905002,3.34702 0.89694,0.77116 1.52168,1.08825 2.67297,1.35446 1.55737,0.36404 3.95367,0.52065 4.9934,0.32489 1.19145,-0.21919 2.68635,-0.98257 3.79749,-1.93382 0.49978,-0.42669 1.01742,-1.08044 1.44134,-1.82815 0.52211,-0.9199 0.9371,-2.42312 1.51721,-5.5431 0.42838,-2.27832 0.69613,-3.5349 0.87016,-4.02424 0.17404,-0.48934 0.43286,-0.71637 0.91033,-0.79468 l 0.16956,-0.0272 -0.0268,0.32883 c -0.0357,0.43058 -0.18741,3.32744 -0.25434,4.85022 -0.058,1.28792 -0.0312,3.34701 0.0491,3.95377 0.19635,1.50712 0.81215,3.30395 1.67339,4.88547 0.62919,1.15089 1.16021,1.80073 2.22672,2.72849 0.83001,0.7242 1.31195,1.05302 1.99024,1.35054 0.52655,0.23096 0.94155,0.34842 1.83849,0.50889 0.78092,0.14486 0.80323,0.14095 0.88355,-0.11343 0.0223,-0.0783 0.0848,-0.34449 0.13833,-0.59113 0.12496,-0.59503 0.0982,-0.81815 -0.14726,-1.25267 -0.16956,-0.30535 -0.24989,-0.39148 -1.02634,-1.06869 -1.36103,-1.19397 -1.72694,-1.61284 -2.26689,-2.59151 -1.24054,-2.24309 -1.70909,-4.07901 -1.94114,-7.59437 -0.11601,-1.71851 -0.0893,-3.17868 0.067,-3.79717 0.0893,-0.368 0.0937,-0.37191 0.18741,-0.13705 0.46409,1.18222 0.79877,2.24702 1.19146,3.81678 0.53995,2.12564 0.65151,2.38008 1.602,3.57014 1.29855,1.62848 2.29812,2.59148 3.71269,3.57408 1.24501,0.8651 2.15534,1.26047 3.42265,1.48364 1.66893,0.29357 2.90054,0.15657 4.25264,-0.4737 0.70952,-0.33272 1.13791,-0.60282 1.43689,-0.90424 0.15172,-0.15267 0.44624,-0.40321 0.65597,-0.55983 0.81661,-0.59109 1.16467,-1.04128 2.15533,-2.77545 0.70952,-1.23704 1.16468,-1.88295 1.99468,-2.81854 0.62027,-0.69679 1.14683,-1.12742 1.76264,-1.44843 l 0.53102,-0.27402 0.20973,-0.35232 c 0.11603,-0.19572 0.3213,-0.52064 0.46409,-0.7242 0.415,-0.60677 0.60689,-1.12351 0.80769,-2.1687 0.18742,-0.99039 0.26329,-1.77724 0.26329,-2.74418 -0.005,-1.09999 -0.0402,-1.25267 -0.52656,-2.11387 -1.02635,-1.8125 -2.28921,-2.84205 -4.35529,-3.55451 -1.01742,-0.3484 -1.91881,-0.55195 -2.96748,-0.66938 -1.35656,-0.15268 -1.72694,-0.16051 -6.69357,-0.16051 -2.75774,0 -4.89076,-0.0155 -4.92646,-0.0353 -0.0491,-0.0272 -0.0491,-0.0391 0.005,-0.0665 0.1428,-0.0705 1.16021,-0.18399 3.94028,-0.44625 3.67253,-0.34841 4.65426,-0.49324 5.84571,-0.88079 1.91883,-0.61853 3.35571,-1.29575 4.864,-2.29005 1.70909,-1.12744 2.5614,-2.14132 3.07904,-3.6641 0.34806,-1.00999 0.60242,-2.53668 0.60242,-3.55841 -0.005,-0.81815 -0.12049,-1.24094 -0.58011,-2.05517 -0.6649,-1.17439 -1.36549,-1.85946 -2.61942,-2.57193 -0.35252,-0.19964 -1.1513,-0.65766 -1.77156,-1.01779 -1.60646,-0.92386 -2.02592,-1.29183 -3.22184,-2.81071 -0.67829,-0.86906 -1.13345,-1.38187 -1.63322,-1.86728 -1.17807,-1.13524 -2.6462,-1.91425 -4.09647,-2.1687 -0.49532,-0.0901 -1.75818,-0.12919 -2.27581,-0.0745 z"
|
||||
id="path1-3-3-3"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00417953" /><path
|
||||
d="m 181.97617,266.85651 c -0.67575,0.64029 -1.01388,1.06776 -1.53142,1.94677 -0.82591,1.402 -1.43323,3.05558 -1.61859,4.41795 -0.10501,0.74073 -0.14474,2.1965 -0.0812,2.79453 0.0449,0.41641 0.28862,0.90832 1.13586,2.28156 0.4312,0.70353 0.66429,1.06698 1.92402,3.01229 1.1934,1.84589 1.7576,2.78457 1.76538,2.93802 0.008,0.12563 -0.679,-0.50471 -2.94617,-2.69417 -3.24722,-3.13763 -3.84604,-3.63997 -4.97973,-4.16083 -1.68478,-0.76832 -4.10447,-0.62779 -6.50269,0.37974 -1.20085,0.50514 -2.01813,1.12178 -2.91522,2.19577 -0.77918,0.93815 -1.31147,1.90587 -1.74142,3.19138 -0.38776,1.15305 -0.53286,1.89258 -0.74653,3.76389 -0.20177,1.75747 -0.27852,2.79987 -0.24285,3.26893 0.0145,0.16203 -0.009,0.27552 -0.0772,0.3961 -0.11736,0.20827 -0.15058,0.30199 -0.56677,1.54057 -0.46093,1.38212 -0.64309,1.99519 -0.77308,2.63208 -0.27025,1.31807 -0.25296,2.21559 0.0684,3.19451 0.21449,0.65542 0.3892,0.97253 0.88059,1.60266 0.60431,0.7668 1.15373,1.25688 1.62856,1.43525 0.40772,0.15685 1.53713,0.2848 2.21873,0.25469 1.06028,-0.0468 3.02671,-0.54603 4.32722,-1.09559 1.70709,-0.72416 3.21702,-1.59353 6.45478,-3.71296 2.61931,-1.71416 3.6189,-2.33386 3.93789,-2.44144 l 0.15029,-0.0513 -0.0391,0.19387 c -0.0515,0.23528 -0.19464,0.41769 -0.73398,0.9172 -0.57692,0.53738 -1.38886,1.21831 -2.94579,2.46507 -2.86604,2.29471 -4.05453,3.33228 -4.82441,4.21777 -1.02926,1.18432 -1.92543,3.264 -2.11272,4.89652 -0.19279,1.71872 0.12071,2.88127 1.28889,4.77374 0.4102,0.66956 0.86603,1.25404 1.0807,1.3857 0.29919,0.18988 1.32282,0.42613 2.68218,0.61934 0.9859,0.13767 1.66933,0.17448 2.65257,0.13657 l 0.93618,-0.0338 0.73652,0.30584 c 0.40517,0.16793 0.90034,0.35798 1.10167,0.4224 1.20483,0.37532 2.97105,0.66689 4.18203,0.69137 1.14227,0.0225 1.8129,-0.12216 2.86802,-0.62038 1.42954,-0.67109 3.39989,-1.99764 4.10501,-2.76527 0.81094,-0.87594 1.551,-2.33064 1.88304,-3.69146 0.15001,-0.61124 0.18507,-1.39859 0.0932,-2.19803 -0.11263,-0.98388 -0.64069,-2.32822 -1.9575,-4.9494 -0.95783,-1.91694 -1.4614,-2.99312 -1.60274,-3.45416 -0.14127,-0.46104 -0.067,-0.782 0.26333,-1.12607 l 0.11765,-0.12184 0.16576,0.25561 c 0.21655,0.33508 1.74296,2.53621 2.55542,3.68556 0.68604,0.97289 1.87672,2.45652 2.28443,2.85018 1.01026,0.97967 2.51442,1.91816 4.08896,2.55231 1.14775,0.45998 1.9338,0.61405 3.29816,0.64862 1.06302,0.0285 1.6282,-0.0218 2.32975,-0.21281 0.5446,-0.14832 0.93714,-0.31233 1.73252,-0.73457 0.69541,-0.36398 0.71074,-0.3802 0.62928,-0.6138 -0.0268,-0.0705 -0.12909,-0.3019 -0.22718,-0.51371 -0.23993,-0.5085 -0.38765,-0.65493 -0.82719,-0.82384 -0.30658,-0.12047 -0.41856,-0.13492 -1.41286,-0.16137 -1.74681,-0.0514 -2.27202,-0.13652 -3.25188,-0.52473 -2.24814,-0.88795 -3.65889,-1.94345 -5.83794,-4.36435 -1.06726,-1.18192 -1.87572,-2.26149 -2.10432,-2.80592 -0.13894,-0.32171 -0.1378,-0.32718 0.0693,-0.21249 1.0359,0.58207 1.90353,1.15641 3.10353,2.06365 1.63136,1.22361 1.86349,1.34186 3.28575,1.63722 1.94456,0.40544 3.27637,0.50592 4.94514,0.37119 1.46891,-0.11838 2.40822,-0.37767 3.52998,-0.97701 1.47709,-0.78951 2.36624,-1.62971 3.0698,-2.90161 0.36807,-0.66889 0.55097,-1.12316 0.6145,-1.52243 0.0324,-0.20242 0.12132,-0.56194 0.19702,-0.8021 0.30538,-0.92146 0.32292,-1.45858 0.11565,-3.31723 -0.14562,-1.32753 -0.15518,-2.07161 -0.035,-3.25201 0.0912,-0.88041 0.25999,-1.5106 0.56112,-2.11463 l 0.26129,-0.51882 -0.0355,-0.38269 c -0.02,-0.21234 -0.0435,-0.57237 -0.047,-0.80647 -0.0188,-0.69142 -0.1617,-1.18315 -0.59777,-2.06513 -0.41543,-0.83401 -0.80282,-1.45273 -1.35208,-2.15699 -0.62876,-0.79817 -0.74312,-0.88822 -1.61417,-1.22307 -1.83539,-0.70311 -3.41173,-0.69377 -5.43857,0.0294 -0.9967,0.3579 -1.82002,0.75157 -2.71008,1.29644 -1.1518,0.70434 -1.44705,0.9213 -5.34648,3.90712 -2.16519,1.65789 -3.84869,2.92893 -3.88796,2.93596 -0.054,0.009 -0.0608,10e-4 -0.0338,-0.0515 0.0721,-0.13718 0.80639,-0.83149 2.84013,-2.69382 2.6855,-2.4616 3.37401,-3.15727 4.08931,-4.15582 1.15518,-1.60406 1.89863,-2.96113 2.51803,-4.59207 0.70142,-1.84864 0.79467,-3.09948 0.3361,-4.51978 -0.30049,-0.94486 -0.96796,-2.20974 -1.54836,-2.95392 -0.46865,-0.59288 -0.79949,-0.83139 -1.62286,-1.14813 -1.18913,-0.45564 -2.12833,-0.53342 -3.51754,-0.29852 -0.39015,0.0666 -1.27749,0.2131 -1.96905,0.3237 -1.78606,0.29293 -2.32442,0.27703 -4.12615,-0.11028 -1.02621,-0.2252 -1.67487,-0.32508 -2.34298,-0.37816 -1.5698,-0.11863 -3.16497,0.19659 -4.44811,0.88336 -0.44007,0.23218 -1.45377,0.96289 -1.82913,1.31389 z"
|
||||
id="path1-3-3-3-6"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00399432"
|
||||
inkscape:transform-center-x="323.33333"
|
||||
inkscape:transform-center-y="-3.4874273" /><path
|
||||
d="m 309.70135,218.68714 c -0.77928,0.0869 -1.22459,0.20605 -2.02242,0.54734 -1.27283,0.54414 -2.53081,1.38448 -3.35835,2.24735 -0.45271,0.46686 -1.232,1.47462 -1.49918,1.93182 -0.18554,0.31876 -0.27831,0.79848 -0.42674,2.22804 -0.0779,0.73086 -0.11133,1.11402 -0.28204,3.17139 -0.16327,1.95114 -0.2746,2.92026 -0.34882,3.03298 -0.0594,0.0934 -0.18924,-0.72446 -0.56034,-3.49982 -0.53065,-3.97634 -0.66795,-4.6557 -1.15037,-5.63771 -0.7199,-1.4553 -2.39721,-2.66591 -4.50869,-3.25189 -1.05761,-0.29299 -1.91853,-0.29943 -3.0689,-0.0257 -1.00193,0.24147 -1.85543,0.63749 -2.80541,1.31362 -0.8535,0.60532 -1.33221,1.04962 -2.44175,2.25702 -1.04276,1.13334 -1.63278,1.82879 -1.85172,2.17973 -0.0743,0.12236 -0.14844,0.18997 -0.25606,0.23827 -0.18553,0.0837 -0.25604,0.13199 -1.17263,0.78238 -1.02049,0.72765 -1.45837,1.0625 -1.87398,1.44243 -0.86092,0.7856 -1.31365,1.42953 -1.60681,2.29564 -0.19668,0.57954 -0.24492,0.89829 -0.24492,1.60983 0.004,0.86932 0.11504,1.51326 0.33768,1.89642 0.18926,0.33162 0.87207,1.03351 1.33964,1.38123 0.72733,0.54093 2.2896,1.25249 3.43626,1.56803 1.50661,0.41212 2.95756,0.61494 6.20085,0.86928 2.62358,0.20607 3.60697,0.3091 3.87415,0.40571 l 0.12617,0.0451 -0.12617,0.11591 c -0.15585,0.13846 -0.34511,0.18996 -0.96112,0.25114 -0.66053,0.0676 -1.55113,0.10948 -3.22844,0.14809 -3.08745,0.0708 -4.41223,0.161 -5.38076,0.37027 -1.29509,0.28013 -2.96499,1.26535 -3.93353,2.31819 -1.01677,1.11082 -1.41012,2.10247 -1.61423,4.07292 -0.0743,0.69547 -0.0743,1.35549 0,1.56479 0.1002,0.29621 0.65683,1.01742 1.45838,1.88994 0.58261,0.63107 1.01678,1.02709 1.68845,1.53258 l 0.63827,0.48296 0.33026,0.61497 c 0.18183,0.33808 0.41191,0.74052 0.5121,0.89508 0.60488,0.91761 1.62536,2.07993 2.41577,2.75284 0.74589,0.63427 1.26542,0.89507 2.22282,1.11402 1.29509,0.29941 3.28783,0.42823 4.15245,0.26722 0.9908,-0.18028 2.23394,-0.80815 3.15796,-1.59053 0.41561,-0.35094 0.84607,-0.88864 1.1986,-1.50361 0.43418,-0.7566 0.77928,-1.99297 1.2617,-4.55909 0.35623,-1.87386 0.57889,-2.90737 0.72361,-3.30984 0.14473,-0.40247 0.35996,-0.5892 0.75702,-0.65361 l 0.14101,-0.0224 -0.0223,0.27046 c -0.0297,0.35414 -0.15585,2.73674 -0.21151,3.9892 -0.0482,1.05928 -0.0259,2.75284 0.0408,3.25189 0.16328,1.23958 0.67537,2.71743 1.39157,4.01819 0.52323,0.94658 0.96482,1.48106 1.85172,2.24412 0.69022,0.59564 1.091,0.86609 1.65506,1.11079 0.43787,0.18996 0.78298,0.28657 1.52887,0.41856 0.6494,0.11914 0.66795,0.11592 0.73475,-0.0933 0.0185,-0.0644 0.0705,-0.28334 0.11503,-0.4862 0.10392,-0.4894 0.0817,-0.67291 -0.12246,-1.03029 -0.141,-0.25114 -0.2078,-0.32198 -0.85349,-0.87898 -1.13182,-0.98201 -1.43611,-1.32652 -1.88512,-2.13146 -1.03162,-1.84488 -1.42126,-3.35489 -1.61424,-6.2462 -0.0965,-1.41343 -0.0743,-2.61439 0.0557,-3.12309 0.0743,-0.30267 0.0779,-0.30589 0.15585,-0.11272 0.38593,0.97236 0.66425,1.84813 0.99081,3.13922 0.44901,1.7483 0.54178,1.95757 1.3322,2.93637 1.07986,1.33938 1.91109,2.13143 3.08744,2.9396 1.03533,0.71152 1.79235,1.03671 2.84623,1.22026 1.38787,0.24145 2.41206,0.12878 3.53646,-0.38961 0.59002,-0.27366 0.94627,-0.49581 1.1949,-0.74372 0.12617,-0.12557 0.37109,-0.33163 0.5455,-0.46045 0.67908,-0.48615 0.96852,-0.85642 1.79235,-2.28275 0.59002,-1.01743 0.96853,-1.54868 1.65875,-2.31818 0.51581,-0.5731 0.95369,-0.92728 1.46579,-1.1913 l 0.44159,-0.22538 0.17441,-0.28978 c 0.0965,-0.16097 0.26719,-0.42821 0.38594,-0.59564 0.34511,-0.49904 0.50468,-0.92405 0.67166,-1.7837 0.15586,-0.81457 0.21895,-1.46174 0.21895,-2.25703 -0.004,-0.90472 -0.0334,-1.03029 -0.43788,-1.73861 -0.8535,-1.49074 -1.90368,-2.33752 -3.62181,-2.9235 -0.84608,-0.28656 -1.59567,-0.45397 -2.46773,-0.55056 -1.1281,-0.12557 -1.4361,-0.13202 -5.5663,-0.13202 -2.29331,0 -4.06711,-0.0128 -4.09679,-0.029 -0.0408,-0.0224 -0.0408,-0.0322 0.004,-0.0547 0.11876,-0.058 0.96482,-0.15132 3.2767,-0.36703 3.05404,-0.28656 3.87043,-0.40568 4.86123,-0.72443 1.59568,-0.50872 2.79057,-1.06572 4.04485,-1.88352 1.42126,-0.92729 2.13004,-1.76118 2.5605,-3.01364 0.28944,-0.83069 0.50097,-2.08636 0.50097,-2.92671 -0.004,-0.67291 -0.1002,-1.02065 -0.48242,-1.69034 -0.55292,-0.96591 -1.13553,-1.52936 -2.17828,-2.11535 -0.29315,-0.1642 -0.95741,-0.54091 -1.47321,-0.83711 -1.33592,-0.75986 -1.68473,-1.0625 -2.67925,-2.31175 -0.56406,-0.71478 -0.94256,-1.13656 -1.35817,-1.53579 -0.97967,-0.93372 -2.20055,-1.57444 -3.40658,-1.78371 -0.4119,-0.0741 -1.46208,-0.10626 -1.89254,-0.0612 z"
|
||||
id="path1-3-3-2"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00345656" /><path
|
||||
d="m 434.17193,103.02813 c -0.71225,0.32793 -1.09736,0.58128 -1.74709,1.15649 -1.03665,0.91735 -1.96592,2.11115 -2.47956,3.19075 -0.28262,0.58569 -0.70482,1.78761 -0.8144,2.30569 -0.0757,0.36098 -0.0126,0.8455 0.29675,2.24905 0.15627,0.71819 0.24522,1.09238 0.73122,3.0988 0.45959,1.90326 0.65918,2.85811 0.62424,2.98847 -0.027,0.10736 -0.4078,-0.62798 -1.63417,-3.14519 -1.75608,-3.60681 -2.10037,-4.20834 -2.86754,-4.98842 -1.14163,-1.15448 -3.11488,-1.77516 -5.30345,-1.66626 -1.09607,0.055 -1.9152,0.3201 -2.9208,0.94223 -0.87487,0.54476 -1.56019,1.18945 -2.24886,2.13038 -0.6194,0.84334 -0.9338,1.41581 -1.60657,2.91123 -0.63271,1.40409 -0.97365,2.24998 -1.07091,2.65202 -0.032,0.13953 -0.0811,0.22706 -0.16798,0.30679 -0.14972,0.13788 -0.20143,0.20592 -0.86652,1.11191 -0.73935,1.01204 -1.04948,1.46776 -1.32427,1.95926 -0.56965,1.01678 -0.79652,1.77053 -0.80196,2.6849 -0.004,0.61199 0.0505,0.92971 0.2746,1.60503 0.27761,0.82381 0.58582,1.4 0.91781,1.69353 0.28408,0.25513 1.15321,0.70623 1.7065,0.88898 0.86069,0.28431 2.56757,0.46758 3.75525,0.40589 1.55973,-0.0834 3.00071,-0.34791 6.15903,-1.12806 2.55495,-0.63077 3.52074,-0.84273 3.80475,-0.83519 l 0.13395,0.003 -0.0832,0.14975 c -0.10431,0.1805 -0.26771,0.28899 -0.8331,0.54108 -0.60562,0.27221 -1.43769,0.59247 -3.01747,1.15742 -2.908,1.03966 -4.13694,1.54254 -4.99026,2.04621 -1.14094,0.67379 -2.41552,2.13484 -3.00315,3.43915 -0.61514,1.37454 -0.67613,2.43961 -0.24921,4.37405 0.14854,0.68348 0.35642,1.3099 0.49286,1.48515 0.1884,0.24957 0.94386,0.75875 1.97943,1.33439 0.75173,0.41544 1.28854,0.65456 2.08523,0.92276 l 0.7579,0.25734 0.50715,0.47965 c 0.27906,0.2636 0.62419,0.57308 0.76796,0.68822 0.86312,0.68038 2.19775,1.46212 3.15988,1.85182 0.9077,0.36705 1.48293,0.45094 2.46057,0.35719 1.32347,-0.12374 3.25536,-0.62914 4.02526,-1.05428 0.88358,-0.48318 1.86569,-1.47065 2.49625,-2.50425 0.28392,-0.46398 0.52311,-1.1099 0.66399,-1.8046 0.17378,-0.85485 0.11189,-2.13698 -0.2385,-4.72444 -0.25212,-1.89068 -0.36632,-2.94172 -0.35573,-3.36929 0.0106,-0.42757 0.15606,-0.67259 0.51262,-0.85878 l 0.12678,-0.0657 0.064,0.26371 c 0.0833,0.34547 0.71408,2.64653 1.05574,3.85278 0.2879,1.02054 0.84249,2.62088 1.06298,3.07352 0.5454,1.12506 1.49691,2.36639 2.58636,3.37536 0.79474,0.7336 1.3822,1.10178 2.4643,1.54666 0.8427,0.34792 1.30827,0.47837 1.92069,0.53295 0.47541,0.0424 0.83339,0.0254 1.58289,-0.0843 0.65387,-0.0915 0.67046,-0.10036 0.66796,-0.31997 -0.003,-0.067 -0.0223,-0.29113 -0.044,-0.49769 -0.0555,-0.49722 -0.13441,-0.66439 -0.44074,-0.93928 -0.21293,-0.19394 -0.29864,-0.24014 -1.08691,-0.56541 -1.38351,-0.57554 -1.78083,-0.80667 -2.46052,-1.42921 -1.56019,-1.42605 -2.40561,-2.73647 -3.49945,-5.41983 -0.53678,-1.3111 -0.89398,-2.45792 -0.93082,-2.98168 -0.0248,-0.31066 -0.0224,-0.31485 0.11241,-0.15607 0.67255,0.80131 1.21255,1.54485 1.92915,2.66736 0.97682,1.51789 1.13078,1.68729 2.18926,2.36731 1.44677,0.93108 2.48516,1.421 3.85619,1.81752 1.20674,0.3492 2.02765,0.4194 3.08571,0.26166 1.39327,-0.20798 2.32985,-0.6375 3.23374,-1.48366 0.47379,-0.44557 0.74194,-0.76863 0.89983,-1.08223 0.0802,-0.15892 0.24774,-0.43163 0.3727,-0.60883 0.49139,-0.6753 0.64948,-1.11789 0.98212,-2.7311 0.23953,-1.15148 0.43144,-1.77491 0.84416,-2.72265 0.30904,-0.70639 0.61308,-1.18046 1.01595,-1.59234 l 0.34813,-0.353 0.0743,-0.32997 c 0.0409,-0.18317 0.11872,-0.49057 0.17869,-0.68688 0.17036,-0.58234 0.18794,-1.03598 0.0756,-1.90446 -0.10864,-0.8222 -0.2526,-1.45631 -0.50309,-2.21112 -0.28876,-0.85741 -0.35622,-0.96733 -0.96321,-1.51219 -1.2796,-1.14604 -2.54304,-1.61894 -4.35828,-1.63393 -0.89328,-0.005 -1.65744,0.0717 -2.51554,0.25473 -1.11023,0.23614 -1.40459,0.32703 -5.32456,1.62793 -2.17659,0.72233 -3.86413,1.26888 -3.8974,1.26285 -0.0458,-0.008 -0.0489,-0.0177 -0.0134,-0.0532 0.0944,-0.0925 0.86805,-0.44751 2.99432,-1.38042 2.80833,-1.23391 3.54565,-1.60411 4.38562,-2.21871 1.35423,-0.98542 2.31286,-1.89043 3.24571,-3.06167 1.05685,-1.32775 1.4669,-2.34244 1.48096,-3.66673 0.0131,-0.87958 -0.18167,-2.13796 -0.44636,-2.93554 -0.21574,-0.6374 -0.41657,-0.93714 -0.99027,-1.45235 -0.82901,-0.74259 -1.55944,-1.09386 -2.73369,-1.32158 -0.32994,-0.0635 -1.07905,-0.21183 -1.66189,-0.33049 -1.50726,-0.3004 -1.93364,-0.47777 -3.27101,-1.35019 -0.76049,-0.50074 -1.25257,-0.78183 -1.77278,-1.02983 -1.2239,-0.57763 -2.58444,-0.80119 -3.795,-0.61995 -0.41428,0.0594 -1.42113,0.35967 -1.81549,0.53802 z"
|
||||
id="path1-3-3-2-0"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00345656" /><path
|
||||
d="m 99.090959,92.821662 c -0.71225,0.32793 -1.09736,0.58128 -1.74709,1.15649 -1.03665,0.91735 -1.96592,2.11115 -2.47956,3.19075 -0.28262,0.58569 -0.70482,1.78761 -0.8144,2.30569 -0.0757,0.36098 -0.0126,0.845498 0.29675,2.249048 0.15627,0.71819 0.24522,1.09238 0.73122,3.0988 0.45959,1.90326 0.65918,2.85811 0.62424,2.98847 -0.027,0.10736 -0.4078,-0.62798 -1.63417,-3.14519 -1.75608,-3.60681 -2.10037,-4.20834 -2.86754,-4.988418 -1.14163,-1.15448 -3.11488,-1.77516 -5.30345,-1.66626 -1.09607,0.055 -1.9152,0.3201 -2.9208,0.94223 -0.87487,0.54476 -1.56019,1.189448 -2.24886,2.130378 -0.6194,0.84334 -0.9338,1.41581 -1.60657,2.91123 -0.63271,1.40409 -0.97365,2.24998 -1.07091,2.65202 -0.032,0.13953 -0.0811,0.22706 -0.16798,0.30679 -0.14972,0.13788 -0.20143,0.20592 -0.86652,1.11191 -0.73935,1.01204 -1.04948,1.46776 -1.32427,1.95926 -0.56965,1.01678 -0.79652,1.77053 -0.80196,2.6849 -0.004,0.61199 0.0505,0.92971 0.2746,1.60503 0.27761,0.82381 0.58582,1.4 0.91781,1.69353 0.28408,0.25513 1.15321,0.70623 1.7065,0.88898 0.86069,0.28431 2.56757,0.46758 3.75525,0.40589 1.55973,-0.0834 3.00071,-0.34791 6.15903,-1.12806 2.55495,-0.63077 3.52074,-0.84273 3.80475,-0.83519 l 0.13395,0.003 -0.0832,0.14975 c -0.10431,0.1805 -0.26771,0.28899 -0.8331,0.54108 -0.60562,0.27221 -1.43769,0.59247 -3.01747,1.15742 -2.908,1.03966 -4.13694,1.54254 -4.99026,2.04621 -1.14094,0.67379 -2.41552,2.13484 -3.00315,3.43915 -0.61514,1.37454 -0.67613,2.43961 -0.24921,4.37405 0.14854,0.68348 0.35642,1.3099 0.49286,1.48515 0.1884,0.24957 0.94386,0.75875 1.97943,1.33439 0.75173,0.41544 1.28854,0.65456 2.08523,0.92276 l 0.7579,0.25734 0.50715,0.47965 c 0.27906,0.2636 0.62419,0.57308 0.76796,0.68822 0.86312,0.68038 2.19775,1.46212 3.15988,1.85182 0.9077,0.36705 1.48293,0.45094 2.46057,0.35719 1.32347,-0.12374 3.25536,-0.62914 4.02526,-1.05428 0.88358,-0.48318 1.86569,-1.47065 2.49625,-2.50425 0.28392,-0.46398 0.52311,-1.1099 0.66399,-1.8046 0.17378,-0.85485 0.11189,-2.13698 -0.2385,-4.72444 -0.25212,-1.89068 -0.36632,-2.94172 -0.35573,-3.36929 0.0106,-0.42757 0.15606,-0.67259 0.51262,-0.85878 l 0.12678,-0.0657 0.064,0.26371 c 0.0833,0.34547 0.71408,2.64653 1.055741,3.85278 0.2879,1.02054 0.84249,2.62088 1.06298,3.07352 0.5454,1.12506 1.49691,2.36639 2.58636,3.37536 0.79474,0.7336 1.3822,1.10178 2.4643,1.54666 0.8427,0.34792 1.30827,0.47837 1.92069,0.53295 0.47541,0.0424 0.83339,0.0254 1.58289,-0.0843 0.65387,-0.0915 0.67046,-0.10036 0.66796,-0.31997 -0.003,-0.067 -0.0223,-0.29113 -0.044,-0.49769 -0.0555,-0.49722 -0.13441,-0.66439 -0.44074,-0.93928 -0.21293,-0.19394 -0.29864,-0.24014 -1.08691,-0.56541 -1.38351,-0.57554 -1.78083,-0.80667 -2.46052,-1.42921 -1.56019,-1.42605 -2.40561,-2.73647 -3.49945,-5.41983 -0.53678,-1.3111 -0.89398,-2.45792 -0.93082,-2.98168 -0.0248,-0.31066 -0.0224,-0.31485 0.11241,-0.15607 0.67255,0.80131 1.21255,1.54485 1.92915,2.66736 0.97682,1.51789 1.13078,1.68729 2.18926,2.36731 1.44677,0.93108 2.48516,1.421 3.85619,1.81752 1.20674,0.3492 2.02765,0.4194 3.08571,0.26166 1.39327,-0.20798 2.32985,-0.6375 3.23374,-1.48366 0.47379,-0.44557 0.74194,-0.76863 0.89983,-1.08223 0.0802,-0.15892 0.24774,-0.43163 0.3727,-0.60883 0.49139,-0.6753 0.64948,-1.11789 0.98212,-2.7311 0.23953,-1.15148 0.43144,-1.77491 0.84416,-2.72265 0.30904,-0.70639 0.61308,-1.18046 1.01595,-1.59234 l 0.34813,-0.353 0.0743,-0.32997 c 0.0409,-0.18317 0.11872,-0.49057 0.17869,-0.68688 0.17036,-0.58234 0.18794,-1.03598 0.0756,-1.90446 -0.10864,-0.8222 -0.2526,-1.45631 -0.50309,-2.21112 -0.28876,-0.85741 -0.35622,-0.96733 -0.96321,-1.51219 -1.2796,-1.14604 -2.54304,-1.61894 -4.35828,-1.63393 -0.89328,-0.005 -1.65744,0.0717 -2.51554,0.25473 -1.11023,0.23614 -1.40459,0.32703 -5.32456,1.62793 -2.17659,0.72233 -3.86413,1.26888 -3.8974,1.26285 -0.0458,-0.008 -0.0489,-0.0177 -0.0134,-0.0532 0.0944,-0.0925 0.86805,-0.44751 2.99432,-1.38042 2.80833,-1.23391 3.54565,-1.60411 4.38562,-2.21871 1.35423,-0.98542 2.31286,-1.89043 3.24571,-3.06167 1.05685,-1.32775 1.4669,-2.34244 1.48096,-3.66673 0.0131,-0.87958 -0.18167,-2.137958 -0.44636,-2.935538 -0.21574,-0.6374 -0.41657,-0.93714 -0.99027,-1.45235 -0.82901,-0.74259 -1.55944,-1.09386 -2.73369,-1.32158 -0.32994,-0.0635 -1.07905,-0.21183 -1.66189,-0.33049 -1.50726,-0.3004 -1.93364,-0.47777 -3.27101,-1.35019 -0.76049,-0.50074 -1.25257,-0.78183 -1.77278,-1.02983 -1.2239,-0.57763 -2.58444,-0.80119 -3.795,-0.61995 -0.41428,0.0594 -1.421131,0.35967 -1.815491,0.53802 z"
|
||||
id="path1-3-3-2-0-4"
|
||||
style="fill:#e5ffd5;fill-opacity:1;stroke:none;stroke-width:0.00345656" /></svg>
|
||||
|
After Width: | Height: | Size: 56 KiB |
@@ -0,0 +1 @@
|
||||
#3cce5bff
|
||||
@@ -0,0 +1,211 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
fill="none"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg7"
|
||||
sodipodi:docname="EdenLogoLoveWhiteV3.svg"
|
||||
inkscape:version="1.4.3 (0d15f75, 2025-12-25)"
|
||||
xml:space="preserve"
|
||||
inkscape:export-filename="dev.eden_emu.eden.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata1">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Madeline_Dev</dc:title>
|
||||
<dc:identifier>mailto:madelvidel@gmail.com</dc:identifier>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:date>2025</dc:date>
|
||||
<dc:license
|
||||
rdf:resource="https://www.gnu.org/licenses/gpl-3.0.html" />
|
||||
<dc:rights>2025 Eden Emulator Project</dc:rights>
|
||||
<dc:source>https://git.eden-emu.dev</dc:source>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs7"><linearGradient
|
||||
id="swatch14"
|
||||
inkscape:swatch="solid"><stop
|
||||
style="stop-color:#66003b;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop14" /></linearGradient><linearGradient
|
||||
id="linearGradient1"
|
||||
inkscape:collect="always"><stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.50980395;"
|
||||
offset="0"
|
||||
id="stop1" /><stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop2" /></linearGradient><linearGradient
|
||||
id="linearGradient11"
|
||||
inkscape:collect="always"><stop
|
||||
style="stop-color:#9523a7;stop-opacity:0.50980395;"
|
||||
offset="0"
|
||||
id="stop11" /><stop
|
||||
style="stop-color:#ffabad;stop-opacity:1;"
|
||||
offset="0.99898213"
|
||||
id="stop20" /><stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="0.99898213"
|
||||
id="stop12" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient11"
|
||||
id="linearGradient12"
|
||||
x1="109.74531"
|
||||
y1="106.54533"
|
||||
x2="431.05463"
|
||||
y2="427.85461"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
spreadMethod="reflect"
|
||||
gradientTransform="matrix(1.0945321,0,0,1.0945321,-39.661525,-35.159057)" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1"
|
||||
id="linearGradient2"
|
||||
x1="125.40197"
|
||||
y1="271.834"
|
||||
x2="431.02424"
|
||||
y2="271.834"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0964243,0,0,1.0253208,-40.187969,-20.060025)" /><filter
|
||||
inkscape:label="Light Contour"
|
||||
inkscape:menu="Image Paint and Draw"
|
||||
inkscape:menu-tooltip="Uses vertical specular light to draw lines"
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter11"
|
||||
x="-0.01907517"
|
||||
y="-0.054959154"
|
||||
width="1.0379885"
|
||||
height="1.1092314"><feGaussianBlur
|
||||
in="SourceGraphic"
|
||||
stdDeviation="0.38250006"
|
||||
result="result3"
|
||||
id="feGaussianBlur9" /><feComponentTransfer
|
||||
result="result1"
|
||||
in="result3"
|
||||
id="feComponentTransfer9"><feFuncR
|
||||
type="discrete"
|
||||
tableValues="0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1"
|
||||
id="feFuncR9" /><feFuncG
|
||||
type="discrete"
|
||||
tableValues="0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1"
|
||||
id="feFuncG9" /><feFuncB
|
||||
type="discrete"
|
||||
tableValues="0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1"
|
||||
id="feFuncB9" /></feComponentTransfer><feGaussianBlur
|
||||
result="result5"
|
||||
stdDeviation="0.01"
|
||||
id="feGaussianBlur10" /><feBlend
|
||||
in2="result5"
|
||||
result="result6"
|
||||
mode="lighten"
|
||||
in="result5"
|
||||
id="feBlend10" /><feColorMatrix
|
||||
in="result6"
|
||||
type="luminanceToAlpha"
|
||||
result="result2"
|
||||
id="feColorMatrix10" /><feSpecularLighting
|
||||
surfaceScale="5"
|
||||
result="result9"
|
||||
specularExponent="20"
|
||||
in="result2"
|
||||
specularConstant="1"
|
||||
id="feSpecularLighting10"><feDistantLight
|
||||
azimuth="180"
|
||||
elevation="90"
|
||||
id="feDistantLight10" /></feSpecularLighting><feComposite
|
||||
in2="result6"
|
||||
operator="arithmetic"
|
||||
in="result9"
|
||||
k1="0.4"
|
||||
k3="0.7"
|
||||
result="result3"
|
||||
id="feComposite10"
|
||||
k2="0"
|
||||
k4="0" /><feBlend
|
||||
in2="result1"
|
||||
in="result3"
|
||||
mode="normal"
|
||||
result="result8"
|
||||
id="feBlend11" /><feComposite
|
||||
in2="SourceGraphic"
|
||||
in="result8"
|
||||
operator="in"
|
||||
result="result7"
|
||||
id="feComposite11" /></filter></defs><sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="1.35"
|
||||
inkscape:cx="254.81481"
|
||||
inkscape:cy="260.37037"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7"
|
||||
showguides="false" /><circle
|
||||
style="fill:url(#linearGradient12);fill-opacity:1;stroke:#e4e4e4;stroke-width:14.0448;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="path8"
|
||||
cx="256.2999"
|
||||
cy="257.2999"
|
||||
r="248.67769" /><path
|
||||
id="path15"
|
||||
style="fill:url(#linearGradient2);fill-opacity:1;stroke:#ffffff;stroke-width:16.9642;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.52156866;paint-order:stroke fill markers"
|
||||
d="m 306.72111,24.233031 c 0,0 -11.98397,40.08696 -18.0546,60.431848 -12.96613,9.503601 -21.49377,18.397701 -21.49377,18.397701 0,0 -23.41313,-31.029398 -45.74145,-43.934598 -22.32833,-12.905201 -52.42065,-11.242483 -52.42065,-11.242483 0,0 -12.50052,4e-4 -27.63117,5.537132 -15.13066,5.536732 -21.27107,9.227888 -21.27107,9.227888 0,0 15.35165,-0.410529 37.93799,6.766716 22.58635,7.177243 32.45374,11.484796 32.45374,11.484796 l 31.02752,-6.562453 -8.44161,11.074275 c 0,0 14.80259,8.920284 22.80648,16.917787 8.0039,7.9975 11.73088,12.50812 11.73088,12.50812 0,0 -13.92373,-5.43341 -56.68427,-1.74226 -42.76055,3.69116 -84.86368,56.39265 -84.86368,56.39265 0,0 41.22428,-15.9958 65.5649,-21.32747 24.34062,-5.33166 47.58524,-7.9983 47.58524,-7.9983 0,0 -18.41865,7.3827 -38.15428,38.3474 -19.73564,30.96468 -14.0351,80.18128 -14.0351,80.18128 0,0 31.35774,-59.05848 61.39977,-78.94969 30.04203,-19.89124 36.182,-20.50642 36.182,-20.50642 0,0 -24.1209,48.39514 -33.55015,126.11445 -9.42924,77.71931 30.26089,207.72959 30.26089,207.72959 l 47.80367,-6.97298 c 0,0 -45.61041,-42.24281 -49.55753,-151.33695 -3.94713,-109.09413 16.66479,-174.30453 16.66479,-174.30453 0,0 17.10508,1.23039 42.54213,32.81027 25.43704,31.57987 40.34713,57.41795 40.34713,57.41795 0,0 9.65024,-51.26683 -11.4011,-74.64415 -21.05135,-23.3773 -53.50637,-33.62931 -53.50637,-33.62931 0,0 13.70573,-6.66419 42.10313,-4.71609 28.39738,1.94813 87.30278,27.12897 87.30278,27.12896 0,0 -15.8158,-25.5214 -52.87463,-43.21167 -37.05881,-17.69028 -81.35597,0.29238 -81.35597,0.29238 0,0 4.13589,-15.37277 29.10021,-32.628037 24.96432,-17.25527 56.907,-34.36427 56.907,-34.36427 0,0 -26.3595,1.160335 -55.20025,12.035504 -7.176,2.7059 -14.064,6.299542 -20.36309,10.173104 l 17.40574,-51.051762 z" /><path
|
||||
id="path4-2-6"
|
||||
style="fill:#ffffff;fill-opacity:0.509804;stroke:#ffffff;stroke-width:8.49614;stroke-dasharray:none;stroke-opacity:0.521569"
|
||||
d="m 105.64857,363.95957 a 27.851731,25.309928 0 0 0 -7.115581,35.20471 27.851731,25.309928 0 0 0 5.656921,5.48617 c 7.16052,5.83605 21.58543,14.65841 45.88391,17.847 37.57172,4.93039 41.7105,10.38005 41.71122,10.381 -4.5e-4,-6e-4 -4.13529,-5.45309 4.14459,-39.11953 5.35491,-21.77281 1.40624,-37.16078 -2.05217,-45.31698 a 27.851731,25.309928 0 0 0 -3.63281,-6.75471 27.851731,25.309928 0 0 0 -38.74027,-6.4662 27.851731,25.309928 0 0 0 -7.11556,35.20472 27.851731,25.309928 0 0 0 -38.74025,-6.46618 z" /><path
|
||||
id="path4-2-6-1"
|
||||
style="fill:#ffffff;fill-opacity:0.50980395;stroke:#ffffff;stroke-width:6.89965;stroke-dasharray:none;stroke-opacity:0.519962"
|
||||
d="m 351.29524,378.32915 a 20.862787,22.283365 87.929759 0 0 -28.94663,11.7882 20.862787,22.283365 87.929759 0 0 -1.50914,6.04125 c -1.09835,7.13663 -1.16134,20.16231 7.28339,36.72931 13.0577,25.61689 10.90177,30.69793 10.90138,30.69882 2.4e-4,-5.6e-4 2.16,-5.08045 30.49632,-15.43688 18.32576,-6.69765 27.84648,-16.23659 32.287,-22.14109 a 20.862787,22.283365 87.929759 0 0 3.33646,-5.36755 20.862787,22.283365 87.929759 0 0 -12.45108,-27.05014 20.862787,22.283365 87.929759 0 0 -28.94664,11.78822 20.862787,22.283365 87.929759 0 0 -12.45106,-27.05014 z" /><path
|
||||
id="path4-2-6-1-5"
|
||||
style="fill:#ffffff;fill-opacity:0.50980395;stroke:#ffffff;stroke-width:6.89965;stroke-dasharray:none;stroke-opacity:0.52156866"
|
||||
d="m 83.024352,249.4105 a 22.283365,20.862787 0 0 0 -29.353581,10.73482 22.283365,20.862787 0 0 0 -1.72639,5.98278 c -1.35544,7.0923 -1.88894,20.10721 5.951801,36.96846 12.12378,26.07187 9.7857,31.07171 9.78528,31.07259 2.6e-4,-5.5e-4 2.34212,-4.99911 31.03406,-14.32513 18.555748,-6.03127 28.414858,-15.22005 33.065768,-20.96029 a 22.283365,20.862787 0 0 0 3.52818,-5.24352 22.283365,20.862787 0 0 0 -11.46577,-27.48227 22.283365,20.862787 0 0 0 -29.353588,10.73483 22.283365,20.862787 0 0 0 -11.46576,-27.48227 z" /><path
|
||||
id="path4-2-6-1-9"
|
||||
style="fill:#ffffff;fill-opacity:0.50980395;stroke:#ffffff;stroke-width:5.01078;stroke-dasharray:none;stroke-opacity:0.519962"
|
||||
d="m 320.97602,291.36362 a 16.625347,14.748181 0 0 0 -21.90036,7.58859 16.625347,14.748181 0 0 0 -1.28804,4.2293 c -1.01128,5.01364 -1.40932,14.21406 4.44057,26.1335 9.0454,18.43055 7.30098,21.965 7.30067,21.96562 2e-4,-3.9e-4 1.74743,-3.53394 23.15415,-10.12663 13.84423,-4.26358 21.19999,-10.75925 24.66998,-14.8171 a 16.625347,14.748181 0 0 0 2.63233,-3.70671 16.625347,14.748181 0 0 0 -8.55447,-19.42758 16.625347,14.748181 0 0 0 -21.90037,7.58859 16.625347,14.748181 0 0 0 -8.55446,-19.42758 z" /><path
|
||||
id="path4-2-6-1-9-8"
|
||||
style="fill:#ffffff;fill-opacity:0.50980395;stroke:#ffffff;stroke-width:4.22313;stroke-dasharray:none;stroke-opacity:0.519962"
|
||||
d="m 416.90426,193.13811 a 12.322476,14.134158 82.30909 0 0 -17.56469,8.83612 12.322476,14.134158 82.30909 0 0 -0.59553,3.65007 c -0.27175,4.26676 0.45709,11.92642 6.76182,21.10665 9.74867,14.19503 8.68847,17.32338 8.68827,17.3239 1.2e-4,-3.3e-4 1.06282,-3.12827 18.32699,-11.08266 11.16516,-5.14424 16.60821,-11.37802 19.06101,-15.14093 a 12.322476,14.134158 82.30909 0 0 1.788,-3.37453 12.322476,14.134158 82.30909 0 0 -9.45059,-15.07737 12.322476,14.134158 82.30909 0 0 -17.5647,8.83612 12.322476,14.134158 82.30909 0 0 -9.45058,-15.07737 z" /><path
|
||||
id="path4-2-6-1-9-8-4"
|
||||
style="fill:#ffffff;fill-opacity:0.50980395;stroke:#ffffff;stroke-width:3.48342;stroke-dasharray:none;stroke-opacity:0.519962"
|
||||
d="m 96.169666,99.754795 a 10.296362,11.508677 62.365085 0 0 -7.330189,13.841365 10.296362,11.508677 62.365085 0 0 1.473186,2.6805 c 2.008889,2.93989 6.437543,7.66269 15.415927,10.84633 13.88288,4.92276 14.77391,7.47086 14.77407,7.4713 -1e-4,-2.8e-4 -0.88925,-2.54921 6.69094,-15.67164 4.90232,-8.48655 5.37758,-15.08279 5.10162,-18.6847 a 10.296362,11.508677 62.365085 0 0 -0.5257,-3.042454 10.296362,11.508677 62.365085 0 0 -14.1348,-5.641051 10.296362,11.508677 62.365085 0 0 -7.33021,13.841385 10.296362,11.508677 62.365085 0 0 -14.134844,-5.641035 z" /><path
|
||||
id="path4-2-6-1-9-8-4-9-2"
|
||||
style="fill:#ffffff;fill-opacity:0.5117;stroke:#ffffff;stroke-width:3.05139;stroke-dasharray:none;stroke-opacity:0.519962"
|
||||
d="m 296.64657,233.26347 a 8.8114666,10.319195 80.445391 0 0 -11.58972,8.06989 8.8114666,10.319195 80.445391 0 0 0.0366,2.62543 c 0.35019,3.02392 1.86017,8.32306 7.60386,14.09672 8.8812,8.92759 8.51432,11.23624 8.51426,11.23663 5e-5,-2.5e-4 0.36876,-2.30885 11.85385,-9.72788 7.4277,-4.79799 10.57103,-9.75243 11.86523,-12.65455 a 8.8114666,10.319195 80.445391 0 0 0.86244,-2.55882 8.8114666,10.319195 80.445391 0 0 -8.77837,-9.57865 8.8114666,10.319195 80.445391 0 0 -11.58975,8.06989 8.8114666,10.319195 80.445391 0 0 -8.77842,-9.57866 z" /><path
|
||||
id="path4-2-6-1-9-8-4-9-2-6"
|
||||
style="fill:#ffffff;fill-opacity:0.5117;stroke:#ffffff;stroke-width:2.49738;stroke-dasharray:none;stroke-opacity:0.519962"
|
||||
d="m 403.95446,91.44744 a 7.0950375,8.5844443 82.142743 0 0 -9.64888,6.492875 7.0950375,8.5844443 82.142743 0 0 0.0305,2.112375 c 0.29155,2.43298 1.54866,6.69657 6.33049,11.34195 7.39392,7.18298 7.08848,9.04046 7.08843,9.04078 4e-5,-2.1e-4 0.307,-1.85765 9.86876,-7.82686 6.18383,-3.86038 8.80077,-7.84663 9.87824,-10.18161 a 7.0950375,8.5844443 82.142743 0 0 0.718,-2.05879 7.0950375,8.5844443 82.142743 0 0 -7.30831,-7.706798 7.0950375,8.5844443 82.142743 0 0 -9.64889,6.492875 7.0950375,8.5844443 82.142743 0 0 -7.30834,-7.706797 z" /><path
|
||||
id="path4-2-6-1-9-8-4-9-5"
|
||||
style="fill:#ffffff;fill-opacity:0.5117;stroke:#ffffff;stroke-width:7.54176;stroke-dasharray:none;stroke-opacity:0.521569"
|
||||
d="m 410.46352,265.86621 a 24.802737,22.39469 2.0523303 0 0 -30.17074,15.95063 24.802737,22.39469 2.0523303 0 0 -0.74427,6.61415 c -0.12337,7.7333 1.79614,21.62064 13.65297,38.28529 18.33368,25.76802 16.72835,31.4347 16.72811,31.43572 1.4e-4,-6.3e-4 1.60998,-5.66652 31.32518,-20.02007 19.21759,-9.28266 28.27643,-20.56192 32.27921,-27.37361 a 24.802737,22.39469 2.0523303 0 0 2.8654,-6.11021 24.802737,22.39469 2.0523303 0 0 -17.88248,-27.36631 24.802737,22.39469 2.0523303 0 0 -30.17081,15.95066 24.802737,22.39469 2.0523303 0 0 -17.88257,-27.36625 z" /><path
|
||||
id="path4-2-6-1-9-8-5"
|
||||
style="fill:#ffffff;fill-opacity:0.50980395;stroke:#ffffff;stroke-width:3.6405;stroke-dasharray:none;stroke-opacity:0.519962"
|
||||
d="m 114.43099,189.33754 a 10.333135,12.525309 79.004057 0 0 -14.00848,9.75499 10.333135,12.525309 79.004057 0 0 0.0547,3.08382 c 0.43602,3.54457 2.28588,9.73496 9.26636,16.38295 10.79359,10.27954 10.35819,13.00063 10.3581,13.00111 6e-5,-3e-4 0.4377,-2.72141 14.32197,-11.70923 8.9793,-5.8126 12.76786,-11.70785 14.32433,-15.14812 a 10.333135,12.525309 79.004057 0 0 1.03481,-3.02677 10.333135,12.525309 79.004057 0 0 -10.67161,-11.04688 10.333135,12.525309 79.004057 0 0 -14.00848,9.75501 10.333135,12.525309 79.004057 0 0 -10.6716,-11.04688 z" /><path
|
||||
id="path4-2-6-1-9-8-4-9-2-2"
|
||||
style="fill:#ffffff;fill-opacity:0.5117;stroke:#ffffff;stroke-width:3.62674;stroke-dasharray:none;stroke-opacity:0.519962"
|
||||
d="m 178.56055,273.32338 a 10.656883,12.053184 66.089768 0 0 -7.97821,14.16205 10.656883,12.053184 66.089768 0 0 1.49012,2.79504 c 2.04675,3.07265 6.5954,8.03049 15.94965,11.48124 14.46412,5.33577 15.34612,7.98353 15.34628,7.98398 -8e-5,-2.8e-4 -0.88012,-2.64887 7.3455,-16.0639 5.31973,-8.67576 5.95524,-15.47956 5.74045,-19.20452 a 10.656883,12.053184 66.089768 0 0 -0.48843,-3.15169 10.656883,12.053184 66.089768 0 0 -14.7135,-6.08217 10.656883,12.053184 66.089768 0 0 -7.97826,14.1621 10.656883,12.053184 66.089768 0 0 -14.71355,-6.08215 z" /></svg>
|
||||
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1 @@
|
||||
#e48cc9ff
|
||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 52 KiB |
@@ -18,7 +18,7 @@
|
||||
src/web_service @AleksandrPopovich
|
||||
src/dynarmic @Lizzie
|
||||
src/core @Lizzie @Maufeat @PavelBARABANOV @MrPurple666 @JPikachu
|
||||
src/core/hle @Maufeat @PavelBARABANOV @SDK-Chan
|
||||
src/core/hle @Maufeat @PavelBARABANOV
|
||||
src/core/arm @Lizzie @MrPurple666
|
||||
src/*_room @AleksandrPopovich
|
||||
src/video_core @CamilleLaVey @MaranBr @Wildcard @weakboson
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# AddDependentPackage
|
||||
|
||||
Use `AddDependentPackage` when you have multiple packages that are required to all be from the system, OR bundled. This is useful in cases where e.g. versions must absolutely match.
|
||||
|
||||
## Versioning
|
||||
|
||||
Versioning must be handled by the package itself.
|
||||
|
||||
## Examples
|
||||
|
||||
### Vulkan
|
||||
|
||||
`cpmfile.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"vulkan-headers": {
|
||||
"repo": "KhronosGroup/Vulkan-Headers",
|
||||
"package": "VulkanHeaders",
|
||||
"version": "1.4.317",
|
||||
"hash": "26e0ad8fa34ab65a91ca62ddc54cc4410d209a94f64f2817dcdb8061dc621539a4262eab6387e9b9aa421db3dbf2cf8e2a4b041b696d0d03746bae1f25191272",
|
||||
"git_version": "1.4.342",
|
||||
"tag": "v%VERSION%"
|
||||
},
|
||||
"vulkan-utility-libraries": {
|
||||
"repo": "KhronosGroup/Vulkan-Utility-Libraries",
|
||||
"package": "VulkanUtilityLibraries",
|
||||
"hash": "8147370f964fd82c315d6bb89adeda30186098427bf3efaa641d36282d42a263f31e96e4586bfd7ae0410ff015379c19aa4512ba160630444d3d8553afd1ec14",
|
||||
"git_version": "1.4.342",
|
||||
"tag": "v%VERSION%"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`CMakeLists.txt`:
|
||||
|
||||
```cmake
|
||||
AddDependentPackages(vulkan-headers vulkan-utility-libraries)
|
||||
```
|
||||
|
||||
If Vulkan Headers are installed, but NOT Vulkan Utility Libraries, then CPMUtil will throw an error.
|
||||
@@ -31,6 +31,10 @@ The core of CPMUtil is the [`AddPackage`](./AddPackage.md) function. [`AddPackag
|
||||
|
||||
[`AddJsonPackage`](./AddJsonPackage.md) is the recommended method of usage for CPMUtil.
|
||||
|
||||
## AddDependentPackage
|
||||
|
||||
[`AddDependentPackage`](./AddDependentPackage.md) allows you to add multiple packages such that all of them must be from the system OR bundled.
|
||||
|
||||
## AddQt
|
||||
|
||||
[`AddQt`](./AddQt.md) adds a specific version of Qt to your project.
|
||||
|
||||
@@ -85,6 +85,8 @@ If you have `quazip1_qt6_devel`, uninstall it. It may call `Core5Compat` on CMak
|
||||
|
||||
## OpenBSD
|
||||
|
||||
System boost doesn't have `context` (as of 7.8); so you may need to specify `-DYUZU_USE_CPM=ON -DBoost_FORCE_BUNDLED=ON`.
|
||||
|
||||
After configuration, you may need to modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`.
|
||||
|
||||
`-lc++-experimental` doesn't exist in OpenBSD but the LLVM driver still tries to link against it, to solve just symlink `ln -s /usr/lib/libc++.a /usr/lib/libc++experimental.a`. Builds are currently not working due to lack of `std::jthread` and such, either compile libc++ manually or wait for ports to catch up.
|
||||
|
||||
@@ -22,17 +22,25 @@ Debug logs can be found in General -> Debug -> Open Log Location on desktop, and
|
||||
|
||||
Ignoring SIGSEGV when debugging in host:
|
||||
|
||||
- **gdb**: `handle all nostop pass`.
|
||||
- **gdb**: `handle SIGSEGV nostop pass`.
|
||||
- **lldb**: `pro hand -p true -s false -n false SIGSEGV`.
|
||||
|
||||
## Debugging (guest code)
|
||||
|
||||
### gdb
|
||||
|
||||
Run `./build/bin/eden-cli -c <path to your config file (see logs where you run eden normally to see where it is)> -d -g <path to game>`
|
||||
You must have GDB installed for aarch64 to debug the target. Install it through your package manager, e.g.:
|
||||
* On Arch:
|
||||
* `sudo pacman -Syu aarch64-linux-gnu-gdb`
|
||||
* On Gentoo:
|
||||
* `sudo emerge --ask crossdev`
|
||||
* `sudo crossdev -t aarch64-unknown-linux-gnu --ex-gdb`
|
||||
|
||||
Then hook up an aarch64-gdb (use `yay aarch64-gdb` or `sudo pkg in arch64-gdb` to install)
|
||||
Then type `target remote localhost:1234` and type `c` (for continue) - and then if it crashes just do a `bt` (backtrace) and `layout asm`.
|
||||
Run `./build/bin/eden-cli -c <path to your config file (see logs where you run eden normally to see where it is)> -d -g <path to game>`
|
||||
Or `Enable GDB Stub` at General > Debug, then hook up an aarch64-gdb:
|
||||
* `target remote localhost:6543`
|
||||
|
||||
Type `c` (for continue) and then if it crashes just do a `bt` (backtrace) and `layout asm`
|
||||
|
||||
### gdb cheatsheet
|
||||
|
||||
|
||||
@@ -51,12 +51,11 @@ All other dependencies will be downloaded and built by [CPM](https://github.com/
|
||||
* [fmt](https://fmt.dev/) 8.0.1+
|
||||
* [lz4](http://www.lz4.org)
|
||||
* [nlohmann\_json](https://github.com/nlohmann/json) 3.8+
|
||||
* [OpenSSL](https://www.openssl.org/source/) 1.1.1+
|
||||
* [OpenSSL](https://www.openssl.org/source/) 3+
|
||||
* [ZLIB](https://www.zlib.net/) 1.2+
|
||||
* [zstd](https://facebook.github.io/zstd/) 1.5+
|
||||
* [enet](http://enet.bespin.org/) 1.3+
|
||||
* [Opus](https://opus-codec.org/) 1.3+
|
||||
* [MbedTLS](https://github.com/Mbed-TLS/mbedtls) 3+
|
||||
|
||||
Vulkan 1.3.274+ is also needed:
|
||||
|
||||
@@ -121,7 +120,7 @@ sudo emerge -a \
|
||||
dev-util/vulkan-utility-libraries dev-util/glslang \
|
||||
media-gfx/renderdoc media-libs/libva media-libs/opus media-video/ffmpeg \
|
||||
media-libs/VulkanMemoryAllocator media-libs/libsdl2 media-libs/cubeb \
|
||||
net-libs/enet net-libs/mbedtls \
|
||||
net-libs/enet \
|
||||
sys-libs/zlib \
|
||||
dev-cpp/nlohmann_json dev-cpp/simpleini dev-cpp/cpp-httplib dev-cpp/cpp-jwt \
|
||||
games-util/gamemode \
|
||||
@@ -139,7 +138,6 @@ Required USE flags:
|
||||
|
||||
* `dev-qt/qtbase network concurrent dbus gui widgets`
|
||||
* `dev-libs/quazip qt6`
|
||||
* `net-libs/mbedtls cmac`
|
||||
* `media-libs/libsdl2 haptic joystick sound video`
|
||||
* `dev-cpp/cpp-httplib ssl`
|
||||
|
||||
@@ -151,7 +149,7 @@ Required USE flags:
|
||||
<summary>Arch Linux</summary>
|
||||
|
||||
```sh
|
||||
sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers
|
||||
sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 ninja nlohmann-json openssl opus qt6-base qt6-multimedia qt6-charts sdl2 zlib zstd zip unzip vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers
|
||||
```
|
||||
|
||||
* Building with QT Web Engine requires `qt6-webengine` as well.
|
||||
@@ -164,7 +162,7 @@ sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glsl
|
||||
<summary>Ubuntu, Debian, Mint Linux</summary>
|
||||
|
||||
```sh
|
||||
sudo apt-get install autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libvulkan-dev spirv-tools spirv-headers libusb-1.0-0-dev libxbyak-dev libboost-dev libboost-fiber-dev libboost-context-dev libsdl2-dev libopus-dev libasound2t64 vulkan-utility-libraries-dev
|
||||
sudo apt-get install autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev qt6-charts-dev libvulkan-dev spirv-tools spirv-headers libusb-1.0-0-dev libxbyak-dev libboost-dev libboost-fiber-dev libboost-context-dev libsdl2-dev libopus-dev libasound2t64 vulkan-utility-libraries-dev
|
||||
```
|
||||
|
||||
* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required.
|
||||
@@ -178,7 +176,7 @@ sudo apt-get install autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev l
|
||||
Fedora:
|
||||
|
||||
```sh
|
||||
sudo dnf install autoconf cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel boost jq
|
||||
sudo dnf install autoconf cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel qt6-charts-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel boost jq
|
||||
```
|
||||
|
||||
AlmaLinux (use `YUZU_USE_CPM=ON`):
|
||||
@@ -211,17 +209,15 @@ First, enable the community repository; [see here](https://wiki.alpinelinux.org/
|
||||
# Enable the community repository
|
||||
setup-apkrepos -c
|
||||
# Install
|
||||
apk add g++ git cmake make mbedtls-dev mbedtls-static mesa-dev qt6-qtbase-dev qt6-qtbase-private-dev libquazip1-qt6 ffmpeg-dev libusb-dev libtool boost-dev sdl2-dev zstd-dev vulkan-utility-libraries spirv-tools-dev openssl-dev nlohmann-json lz4-dev opus-dev jq patch
|
||||
apk add g++ git cmake make mesa-dev qt6-qtbase-dev qt6-qtbase-private-dev libquazip1-qt6 ffmpeg-dev qt6-charts-dev libusb-dev libtool boost-dev sdl2-dev zstd-dev vulkan-utility-libraries spirv-tools-dev openssl-dev nlohmann-json lz4-dev opus-dev jq patch
|
||||
```
|
||||
|
||||
`mbedtls-static` has to be specified otherwise `libeverest.a` and `libp256m.a` will fail to be found.
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>Void Linux</summary>
|
||||
|
||||
```sh
|
||||
xbps-install -Su git make cmake clang pkg-config patch mbedtls-devel SPIRV-Tools-devel SPIRV-Headers lz4 liblz4-devel boost-devel ffmpeg6-devel catch2 Vulkan-Utility-Libraries Vulkan-Headers glslang openssl-devel SDL2-devel quazip-qt6-devel qt6-base-devel qt6-qt5compat-devel fmt-devel json-c++ libenet-devel libusb-devel
|
||||
xbps-install -Su git make cmake clang pkg-config patch SPIRV-Tools-devel SPIRV-Headers lz4 liblz4-devel boost-devel ffmpeg6-devel catch2 Vulkan-Utility-Libraries Vulkan-Headers glslang openssl-devel SDL2-devel quazip-qt6-devel qt6-base-devel qt6-qt5compat-devel qt6-charts-devel fmt-devel json-c++ libenet-devel libusb-devel
|
||||
```
|
||||
|
||||
Yes, `nlohmann-json` is just named `json-c++`. Why?
|
||||
@@ -233,6 +229,8 @@ Yes, `nlohmann-json` is just named `json-c++`. Why?
|
||||
|
||||
A convenience script is provided on the root of this project [shell.nix](../shell.nix). Run the usual `nix-shell`.
|
||||
|
||||
If you're going for a pure build (i.e no downloaded deps), use `-DYUZU_USE_CPM=ON -DCPMUTIL_FORCE_SYSTEM=ON`.
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>macOS</summary>
|
||||
@@ -257,7 +255,7 @@ brew install molten-vk
|
||||
<details>
|
||||
<summary>FreeBSD</summary>
|
||||
|
||||
As root run: `pkg install devel/cmake devel/sdl20 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib devel/unordered-dense mbedtls3 vulkan-headers quazip-qt6`
|
||||
As root run: `pkg install devel/cmake devel/sdl20 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/qt6-charts devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib devel/unordered-dense vulkan-headers quazip-qt6`
|
||||
|
||||
If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
|
||||
|
||||
@@ -267,7 +265,7 @@ If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
|
||||
<details>
|
||||
<summary>NetBSD</summary>
|
||||
|
||||
For NetBSD +10.1: `pkgin install git cmake boost fmtlib SDL2 catch2 libjwt spirv-headers spirv-tools ffmpeg7 libva nlohmann-json jq libopus qt6 mbedtls3 cpp-httplib lz4 vulkan-headers nasm autoconf enet pkg-config libusb1 libcxx`.
|
||||
For NetBSD +10.1: `pkgin install git cmake boost fmtlib SDL2 catch2 libjwt spirv-headers spirv-tools ffmpeg7 libva nlohmann-json jq libopus qt6 cpp-httplib lz4 vulkan-headers nasm autoconf enet pkg-config libusb1 libcxx`.
|
||||
|
||||
[Caveats](./Caveats.md#netbsd).
|
||||
|
||||
@@ -277,7 +275,7 @@ For NetBSD +10.1: `pkgin install git cmake boost fmtlib SDL2 catch2 libjwt spirv
|
||||
|
||||
```sh
|
||||
pkg_add -u
|
||||
pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 libusb1-1.0.27
|
||||
pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 libusb1-1.0.29
|
||||
```
|
||||
|
||||
[Caveats](./Caveats.md#openbsd).
|
||||
@@ -287,7 +285,7 @@ pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gm
|
||||
<summary>DragonFlyBSD</summary>
|
||||
|
||||
```sh
|
||||
pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmake jq nlohmann-json enet spirv-tools sdl2 vulkan-utility-libraries vulkan-headers catch2 libfmt openssl liblz4 boost-libs cpp-httplib qt6-base quazip-qt6 unordered-dense libva-vdpau-driver libva-utils libva-intel-driver
|
||||
pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmake jq nlohmann-json enet spirv-tools sdl2 vulkan-utility-libraries vulkan-headers catch2 libfmt openssl liblz4 boost-libs cpp-httplib qt6-base qt6-charts quazip-qt6 unordered-dense libva-vdpau-driver libva-utils libva-intel-driver
|
||||
```
|
||||
|
||||
[Caveats](./Caveats.md#dragonflybsd).
|
||||
@@ -311,7 +309,7 @@ sudo pkg install qt6 boost glslang libzip library/lz4 libusb-1 nlohmann-json ope
|
||||
|
||||
```sh
|
||||
BASE="git make autoconf libtool automake-wrapper jq patch"
|
||||
MINGW="qt6-base qt6-tools qt6-translations qt6-svg cmake toolchain clang python-pip openssl vulkan-memory-allocator vulkan-devel glslang boost fmt lz4 nlohmann-json zlib zstd enet opus mbedtls libusb unordered_dense openssl SDL2"
|
||||
MINGW="qt6-base qt6-charts qt6-tools qt6-translations qt6-svg cmake toolchain clang python-pip openssl vulkan-memory-allocator vulkan-devel glslang boost fmt lz4 nlohmann-json zlib zstd enet opus libusb unordered_dense openssl SDL2"
|
||||
# Either x86_64 or clang-aarch64 (Windows on ARM)
|
||||
packages="$BASE"
|
||||
for pkg in $MINGW; do
|
||||
@@ -337,7 +335,7 @@ pacman -Syuu --needed --noconfirm $packages
|
||||
<summary>HaikuOS</summary>
|
||||
|
||||
```sh
|
||||
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel qt6_declarative_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt5_devel qt6_5compat_devel mbedtls3_devel glslang qt6_devel
|
||||
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel qt6_declarative_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt5_devel qt6_5compat_devel glslang qt6_devel qt6_charts_devel
|
||||
```
|
||||
|
||||
[Caveats](./Caveats.md#haikuos).
|
||||
|
||||
@@ -82,15 +82,15 @@ You may additionally need the `Qt Extension Pack` extension if building Qt.
|
||||
|
||||
# Build speedup
|
||||
|
||||
If you have an HDD, use ramdisk (build in RAM):
|
||||
If you have an HDD, use ramdisk (build in RAM), approximatedly you need 4GB for a full build with debug symbols:
|
||||
```sh
|
||||
sudo mkdir /tmp/ramdisk
|
||||
sudo chmod 777 /tmp/ramdisk
|
||||
mkdir /tmp/ramdisk
|
||||
chmod 777 /tmp/ramdisk
|
||||
# about 8GB needed
|
||||
sudo mount -t tmpfs -o size=8G myramdisk /tmp/ramdisk
|
||||
mount -t tmpfs -o size=4G myramdisk /tmp/ramdisk
|
||||
cmake -B /tmp/ramdisk
|
||||
cmake --build /tmp/ramdisk -- -j32
|
||||
sudo umount /tmp/ramdisk
|
||||
umount /tmp/ramdisk
|
||||
```
|
||||
|
||||
# Assets and large files
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# CMake Options
|
||||
|
||||
To change these options, add `-DOPTION_NAME=NEWVALUE` to the command line.
|
||||
|
||||
- On Qt Creator, go to Project -> Current Configuration
|
||||
|
||||
Notes:
|
||||
|
||||
- Defaults are marked per-platform.
|
||||
- "Non-UNIX" just means Windows/MSVC and Android (yes, macOS is UNIX
|
||||
- Android generally doesn't need to change anything; if you do, go to `src/android/app/build.gradle.kts`
|
||||
- To set a boolean variable to on, use `ON` for the value; to turn it off, use `OFF`
|
||||
- If a variable is mentioned as being e.g. "ON" for a specific platform(s), that means it is defaulted to OFF on others
|
||||
- TYPE is always boolean unless otherwise specified
|
||||
- Format:
|
||||
- `OPTION_NAME` (TYPE DEFAULT) DESCRIPTION
|
||||
|
||||
## Options
|
||||
|
||||
### Dependencies
|
||||
|
||||
These options control dependencies.
|
||||
|
||||
- `YUZU_USE_BUNDLED_FFMPEG` (ON for non-UNIX) Download a pre-built and configured FFmpeg
|
||||
- `YUZU_USE_EXTERNAL_FFMPEG` (ON for Solaris) Build FFmpeg from source
|
||||
- `YUZU_DOWNLOAD_ANDROID_VVL` (ON) Download validation layer binary for Android
|
||||
- `YUZU_DOWNLOAD_TIME_ZONE_DATA` (ON) Always download time zone binaries
|
||||
- Currently, build fails without this
|
||||
- `YUZU_TZDB_PATH` (string) Path to a pre-downloaded timezone database (useful for nixOS and Gentoo)
|
||||
- `YUZU_USE_BUNDLED_MOLTENVK` (ON, macOS only) Download bundled MoltenVK lib
|
||||
- `YUZU_USE_BUNDLED_OPENSSL` (ON for MSVC, Android, Solaris, and OpenBSD) Download bundled OpenSSL build
|
||||
- `YUZU_USE_EXTERNAL_SDL2` (OFF) Compiles SDL2 from source
|
||||
- `YUZU_USE_BUNDLED_SDL2` (ON for MSVC) Download a prebuilt SDL2
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- `ENABLE_WEB_SERVICE` (ON) Enable multiplayer service
|
||||
- `ENABLE_WIFI_SCAN` (OFF) Enable WiFi scanning (requires iw on Linux) - experimental
|
||||
- `ENABLE_CUBEB` (ON) Enables the cubeb audio backend
|
||||
- This option is subject for removal.
|
||||
- `YUZU_TESTS` (ON) Compile tests - requires Catch2
|
||||
- `ENABLE_LTO` (OFF) Enable link-time optimization
|
||||
- Not recommended on Windows
|
||||
- UNIX may be better off appending `-flto=thin` to compiler args
|
||||
- `USE_FASTER_LINKER` (OFF) Check if a faster linker is available
|
||||
- Not recommended outside of Linux
|
||||
|
||||
### Flavors
|
||||
|
||||
These options control executables and build flavors.
|
||||
|
||||
- `YUZU_LEGACY` (OFF): Apply patches to improve compatibility on some older GPUs at the cost of performance
|
||||
- `NIGHTLY_BUILD` (OFF): This is only used by CI. Do not use this unless you're making your own distribution and know what you're doing.
|
||||
- `YUZU_STATIC_BUILD` (OFF) Attempt to build using static libraries if possible
|
||||
- Not supported on Linux
|
||||
- Automatically set if `YUZU_USE_BUNDLED_QT` is on for non-Linux
|
||||
- `ENABLE_UPDATE_CHECKER` (OFF) Enable update checking functionality
|
||||
- `YUZU_DISABLE_LLVM` (OFF) Do not attempt to link to the LLVM demangler
|
||||
- Really only useful for CI or distribution builds
|
||||
|
||||
**Desktop only**:
|
||||
|
||||
- `YUZU_CMD` (ON) Compile the SDL2 frontend (eden-cli)
|
||||
- `YUZU_ROOM` (OFF) Compile dedicated room functionality into the main executable
|
||||
- `YUZU_ROOM_STANDALONE` (OFF) Compile a separate executable for room functionality
|
||||
- `YUZU_STATIC_ROOM` (OFF) Compile the room executable *only* as a static, portable executable
|
||||
- This is only usable on Alpine Linux.
|
||||
|
||||
### Desktop
|
||||
|
||||
The following options are desktop only.
|
||||
|
||||
- `ENABLE_LIBUSB` (ON) Enable the use of the libusb input frontend (HIGHLY RECOMMENDED)
|
||||
- `ENABLE_OPENGL` (ON) Enable the OpenGL graphics frontend
|
||||
- Unavailable on Windows/ARM64
|
||||
- You probably shouldn't turn this off.
|
||||
|
||||
### Qt
|
||||
|
||||
Also desktop-only, but apply strictly to Qt
|
||||
|
||||
- `ENABLE_QT` (ON) Enable the Qt frontend (recommended)
|
||||
- `ENABLE_QT_TRANSLATION` (OFF) Enable translations for the Qt frontend
|
||||
- `YUZU_USE_BUNDLED_QT` (ON for MSVC) Download bundled Qt binaries
|
||||
- Not recommended on Linux. For Windows and macOS, the provided build is statically linked.
|
||||
- `YUZU_QT_MIRROR` (string) What mirror to use for downloading the bundled Qt libraries
|
||||
- `YUZU_USE_QT_MULTIMEDIA` (OFF) Use QtMultimedia for camera support
|
||||
- `YUZU_USE_QT_WEB_ENGINE` (OFF) Use QtWebEngine for web applet implementation (requires the huge QtWebEngine dependency; not recommended)
|
||||
- `USE_DISCORD_PRESENCE` (OFF) Enables Discord Rich Presence (Qt frontend only)
|
||||
|
||||
### Retired Options
|
||||
|
||||
The following options were a part of Eden at one point, but have since been retired.
|
||||
|
||||
- `ENABLE_OPENSSL` - MbedTLS was fully replaced with OpenSSL in [#3606](https://git.eden-emu.dev/eden-emu/eden/pulls/3606), because OpenSSL straight-up performs better.
|
||||
- `ENABLE_SDL2` - While technically possible to *not* use SDL2 on desktop, this is **NOT** a supported configuration under any means, and adding this matrix to our build system was not worth the effort.
|
||||
- `YUZU_USE_CPM` - This option once had a purpose, but that purpose has long since passed us by. *All* builds use CPMUtil to manage dependencies now.
|
||||
- If you want to *force* the usage of system dependencies, use `-DCPMUTIL_FORCE_SYSTEM=ON`.
|
||||
|
||||
See `src/dynarmic/CMakeLists.txt` for additional options--usually, these don't need changed
|
||||
@@ -3,6 +3,7 @@
|
||||
This contains documentation created by developers. This contains build instructions, guidelines, instructions/layouts for [cool stuff we made](./CPMUtil), and more.
|
||||
|
||||
- **[General Build Instructions](Build.md)**
|
||||
- **[CMake Options](Options.md)**
|
||||
- **[Cross Compiling](CrossCompile.md)**
|
||||
- **[Development Guidelines](Development.md)**
|
||||
- **[Dependencies](Deps.md)**
|
||||
|
||||
@@ -18,7 +18,7 @@ First of all, you MUST have a valid reason to sign up for our Git. Valid reasons
|
||||
The following are not valid reasons to sign up:
|
||||
|
||||
- I want to contribute to Eden.
|
||||
* Be at least somewhat specific!
|
||||
* Be at least somewhat specific! We always welcome contributors and developers, but generic "I want to contribute" messages don't give us enough information.
|
||||
- I want to support Eden.
|
||||
* If you wish to support us through development, be more specific; otherwise, to support us, check out our [donations page](https://eden-emu.dev/donations).
|
||||
- I want to report issues.
|
||||
@@ -41,17 +41,36 @@ Email: <Your Desired Email>
|
||||
I wish to sign up because... <your reason here>
|
||||
```
|
||||
|
||||
Email notifications are disabled for the time being, so you don't have to use a real email. If you wish to remain anonymous, either send a separate email asking for access to a shared anonymous account, *or* create a fake username and email.
|
||||
Email notifications are disabled for the time being, so you don't have to use a real email. If you wish to remain anonymous, either send a separate email asking for access to a shared anonymous account, *or* create a fake username and email. Do note that the email you sign up with is used to accredit commits on the web UI, and *must* match your configured GPG key.
|
||||
|
||||
## Patches
|
||||
|
||||
In general, PRs are the preferred method of tracking patches, as they allow us to go through our standard triage, CI, and testing process without having to deal with the minutiae of incremental patches. However, we also understand that many people prefer to use raw patches, and that's totally okay! While we currently don't have a mailing list, we do accept email patches. To do so:
|
||||
|
||||
1. Make your changes on a clean copy of the master branch
|
||||
2. Commit your changes with a descriptive, well-formed message (see the [commit message docs](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/Development.md#pull-requests)), and a proper description thoroughly explaining your changes.
|
||||
* Note that we don't need to know all the individual details about your code. A description explaining the motivation and general implementation of your changes is enough, alongside caveats and any potential blockers.
|
||||
3. Format your patch with `git format-patch -1 HEAD`.
|
||||
4. Email us with the subject `[Eden] [PATCH] <brief patch description...>`, with a brief description of your patch, and the previously-formatted patch file as an attachment.
|
||||
* If you don't include the first two bracketed parts, your email may be lost!
|
||||
|
||||
The following emails are currently set up to receive and process patches:
|
||||
|
||||
- [eden@eden-emu.dev](mailto:eden@eden-emu.dev]
|
||||
- [crueter@eden-emu.dev](mailto:eden@eden-emu.dev)
|
||||
|
||||
## Instructions
|
||||
|
||||
If you have read everything above and affirm that you will not abuse your access, click the summary below to get the email to send your request to.
|
||||
|
||||
<details>
|
||||
<summary>I affirm that I have read ALL of the information above, and will not abuse my access to Eden, nor will I send unnecessary spam requests or the following email.</summary>
|
||||
<summary>I affirm that I have read ALL of the information above, and will not abuse my access to Eden, nor will I send unnecessary spam to the following email.</summary>
|
||||
|
||||
Email [crueter@crueter.xyz](mailto:crueter@crueter.xyz) with the format above.
|
||||
|
||||
Once your request is processed, you should receive a confirmation email from crueter with your password alongside a link to a repository containing instructions on SSH, etc. Note that you are required to change your password. If your request is rejected, you will receive a notice as such, asking for clarification if needed. If you do not receive a response in 48 hours, you may send another email.
|
||||
|
||||
</details>
|
||||
> [!WARNING]
|
||||
> Some email providers may place the response email in your spam/junk folder; notable offenders include Gmail and Outlook. *Always* ensure to check your Spam/Junk folder, until Google/Microsoft finally end their vendetta against the great evil of my `.xyz` domain.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -286,15 +286,6 @@ Exclusive OR (i.e.: XOR)
|
||||
|
||||
Memory access.
|
||||
|
||||
### Terminal: Interpret
|
||||
|
||||
```c++
|
||||
SetTerm(IR::Term::Interpret{next})
|
||||
```
|
||||
|
||||
This terminal instruction calls the interpreter, starting at `next`.
|
||||
The interpreter must interpret exactly one instruction.
|
||||
|
||||
### Terminal: ReturnToDispatch
|
||||
|
||||
```c++
|
||||
|
||||
@@ -117,11 +117,6 @@ public:
|
||||
MemoryWrite32(vaddr + 4, u32(value >> 32));
|
||||
}
|
||||
|
||||
void InterpreterFallback(u32 pc, size_t num_instructions) override {
|
||||
// This is never called in practice.
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
void CallSVC(u32 swi) override {
|
||||
// Do something.
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ AI is notorious for hallucinating facts out of thin air and sometimes outright l
|
||||
- Code that works, but is extraordinarily verbose or not nearly as efficient as it can be
|
||||
- Code that works well and is written well, but solves a different problem than was intended, or solves the same problem but in a completely incorrect way that will break other things horribly.
|
||||
|
||||
Human-written code will, without exception, always be of infinitely higher quality when properly researched and implemented by someone both familiar with the surrounding code and the programming language in use. LLMs may produce a "good enough" result, but this result is often subpar. Keep in mind: all code is held under a standard of excellence. If your code sucks, it will be rejected. AI-generated code just so happens to be a particularly sucky genre of code, and will thus be held to this same standard.
|
||||
Human-written code will, without exception, always be of infinitely higher quality when properly researched and implemented by someone familiar with *both* the surrounding code and the programming language in use. LLMs may produce a "good enough" result, but this result is often subpar.
|
||||
|
||||
**All code is held under a STRICT STANDARD OF EXCELLENCE**. AI code is no different, and since it often produces subpar or outright terrible code, it will often fail to meet this excellence standard.
|
||||
|
||||
On a lesser-known note, LLM outputs often contain unicode symbols such as emojis or the arrow symbol. Please don't put Unicode symbols in your code. It messes with many an IDE, and the three people viewing your code on Lynx will be very unhappy.
|
||||
|
||||
@@ -25,7 +27,8 @@ On a lesser-known note, LLM outputs often contain unicode symbols such as emojis
|
||||
|
||||
## Acceptable Use
|
||||
|
||||
- As stated previously, AI is good in a few *very specific* cases. In these cases, it's usually fine to use AI, as long as you **explicitly provide notice that it was used**.
|
||||
As stated previously, AI is good in a few *very specific* cases. In these cases, it's usually fine to use AI, as long as you **explicitly provide notice that it was used**.
|
||||
|
||||
- Anything directly outside of the realm of the code written in your PR or patch is none of our business.
|
||||
- This primarily covers research.
|
||||
- However, we *still* strongly discourage this for the reasons mentioned above.
|
||||
@@ -104,4 +107,6 @@ This consolidates profile removal behavior, fixes potential race conditions in t
|
||||
|
||||
This has all of the same problems as the other one. Needlessly verbose, doesn't address *what* it actually fixes ("consolidates profile removal behavior"... okay, why? What does it fix?), etc. It even has the bonus of totally hallucinating the addition of a method!
|
||||
|
||||
On a more "philosophical" note, LLMs tend to be geared towards *corporate language*, as that's what they're trained on. This is why AI-generated commit messages feel like "word salad", and typically pad out the commit message to make it *look* like a lot of things were changed (trust me, it's like that in the corporate world). They typically also drift towards unneeded buzzwords and useless implementation details.
|
||||
|
||||
**Don't use AI for commit messages**.
|
||||
|
||||
@@ -12,12 +12,13 @@ The setting ranges from 0 to 65535 (0x0000 to 0xFFFF), where each bit represents
|
||||
* [Accessing Debug Knobs (dev side)](#accessing-debug-knobs-dev-side)
|
||||
* [Setting Debug Knobs (user side)](#setting-debug-knobs-user-side)
|
||||
* [Bit Manipulation Examples](#bit-manipulation-examples)
|
||||
3. [Examples](#examples)
|
||||
3. [Terminology and user communication](#terminology-and-user-communication)
|
||||
4. [Examples](#examples)
|
||||
|
||||
* [Example 1: Conditional Debug Logging](#example-1-conditional-debug-logging)
|
||||
* [Example 2: Performance Tuning](#example-2-performance-tuning)
|
||||
* [Example 3: Feature Gating](#example-3-feature-gating)
|
||||
4. [Best Practices](#best-practices)
|
||||
5. [Best Practices](#best-practices)
|
||||
|
||||
---
|
||||
|
||||
@@ -77,6 +78,44 @@ To enable specific features, calculate the decimal value by setting the appropri
|
||||
* **Enable bits 0 and 1**: Value = 3 (2^0 + 2^1)
|
||||
* **Enable bit 15**: Value = 32768 (2^15)
|
||||
|
||||
## Terminology and user communication
|
||||
|
||||
There are two main confusions when talking about knobs:
|
||||
|
||||
### Whether it's zero-based or one-based
|
||||
|
||||
Sometimes when an user reports: knobs 1 and 2 gets better performance, dev may get confuse whether he means the knobs 1 and 2 literally, or the 1st and 2nd knobs (knobs 0 and 1).
|
||||
|
||||
Debug knobs are **zero-based**, which means:
|
||||
* The first knob is the knob(0) (or knob0 henceforth), and the last one is the 15 (knob15, likewise)
|
||||
* You can talk: "knob0 is enabled/disabled", "In this video i was using only knobs 0 and 2", etc.
|
||||
|
||||
### Whether one is talking about the knob itself or about the entire parameter value (which represents all knobs)
|
||||
|
||||
Sometimes when an user reports: knob 3 results, it's unclear whether he's referring to knob setting with value 3 (which means both knob 0 and 1 are enabled), or to knob(3) specifically.
|
||||
Whenever you're instructing tests or reporting results, be precise about whether one you're talking to avoid confusion:
|
||||
|
||||
### Setting based terminology
|
||||
|
||||
ALWAYS use the word in PLURAL (knobs), without mentioning which one, to refer to the setting, aka multiple knobs at once:
|
||||
Examples:
|
||||
- **knobs=0**: no knobs enabled
|
||||
- **knobs=1**: knob0 enabled, others disabled
|
||||
- **knobs=2**: knob1 enabled, others disabled
|
||||
- **knobs=3**: knobs 0 and 1 enabled, others disabled
|
||||
|
||||
...
|
||||
|
||||
### Knob based terminology
|
||||
|
||||
Use the word in SINGULAR (knob), or in plural but referring which ones, when meaning multiple knobs at once:
|
||||
Examples:
|
||||
- **knob0**: knob 0 enabled, others disabled
|
||||
- **knob1**: knob 1 enabled, others disabled
|
||||
- **knobs 0 and 1**: knobs 0 and 1 enabled, others disabled
|
||||
|
||||
...
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Conditional Debug Logging
|
||||
|
||||
@@ -6,7 +6,4 @@ Debugging on physical hardware can get tedious and time consuming. Users are emp
|
||||
|
||||
**Standard key prefix**: Allows to redirect the key manager to a file other than `prod.keys` (for example `other` would redirect to `other.keys`). This is useful for testing multiple keysets. Default is `prod`.
|
||||
|
||||
**Changing serial**: Very basic way to set debug values for the serial (and battery number). Developers do not need to write the full serial as it will be writen in-place (that is, it will be filled with the default serial and then overwrite the serial from the beginning).
|
||||
- Battery serial: `YUZU0EMULATOR14022024`
|
||||
- Board serial: `YUZ10000000001`
|
||||
If the user were to set their board serial as `ABC`, then it will be written in-place and the resulting serial would be `ABC10000000001`. There are no underlying checks to ensure correctness of serials other than a hard limit of 16-characters for both.
|
||||
**Changing serial**: Very basic way to set debug values for the serial (and battery number). Developers do not need to write the full serial as only the first digits (excluding the last) will be accoutned for. Region settings will affect the generated serial. The serial corresponds to a non-OLED/Lite console.
|
||||
|
||||
@@ -27,11 +27,7 @@ set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
|
||||
# Xbyak
|
||||
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
|
||||
if (PLATFORM_SUN OR PLATFORM_OPENBSD OR PLATFORM_NETBSD OR PLATFORM_DRAGONFLY)
|
||||
AddJsonPackage(xbyak_sun)
|
||||
else()
|
||||
AddJsonPackage(xbyak)
|
||||
endif()
|
||||
AddJsonPackage(xbyak)
|
||||
endif()
|
||||
|
||||
# enet
|
||||
@@ -45,9 +41,6 @@ if (NOT TARGET enet::enet)
|
||||
add_library(enet::enet ALIAS enet)
|
||||
endif()
|
||||
|
||||
# mbedtls
|
||||
AddJsonPackage(mbedtls)
|
||||
|
||||
# stb
|
||||
add_library(stb stb/stb_dxt.cpp)
|
||||
target_include_directories(stb PUBLIC ./stb)
|
||||
@@ -66,6 +59,9 @@ if (NOT TARGET LLVM::Demangle)
|
||||
add_library(LLVM::Demangle ALIAS demangle)
|
||||
endif()
|
||||
|
||||
# unordered_dense
|
||||
AddJsonPackage(unordered-dense)
|
||||
|
||||
if (YUZU_STATIC_ROOM)
|
||||
return()
|
||||
endif()
|
||||
@@ -83,13 +79,11 @@ endif()
|
||||
# mcl
|
||||
AddJsonPackage(mcl)
|
||||
|
||||
# VulkanUtilityHeaders - pulls in headers and utility libs
|
||||
AddJsonPackage(vulkan-utility-headers)
|
||||
# Vulkan stuff
|
||||
AddDependentPackages(vulkan-headers vulkan-utility-libraries)
|
||||
|
||||
# small hack
|
||||
if (NOT VulkanUtilityLibraries_ADDED)
|
||||
find_package(VulkanHeaders 1.3.274 REQUIRED)
|
||||
endif()
|
||||
# frozen
|
||||
AddJsonPackage(frozen)
|
||||
|
||||
# DiscordRPC
|
||||
if (USE_DISCORD_PRESENCE)
|
||||
@@ -139,8 +133,7 @@ if(ENABLE_CUBEB)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package
|
||||
if (ENABLE_SDL2)
|
||||
if (NOT ANDROID)
|
||||
if (YUZU_USE_EXTERNAL_SDL2)
|
||||
message(STATUS "Using SDL2 from externals.")
|
||||
if (NOT WIN32)
|
||||
@@ -237,18 +230,13 @@ if (VulkanMemoryAllocator_ADDED)
|
||||
endif()
|
||||
|
||||
# httplib
|
||||
if (ENABLE_WEB_SERVICE OR ENABLE_UPDATE_CHECKER OR USE_DISCORD_PRESENCE OR ENABLE_OPENSSL)
|
||||
AddJsonPackage(httplib)
|
||||
endif()
|
||||
AddJsonPackage(httplib)
|
||||
|
||||
# cpp-jwt
|
||||
if (ENABLE_WEB_SERVICE OR ENABLE_UPDATE_CHECKER)
|
||||
AddJsonPackage(cpp-jwt)
|
||||
endif()
|
||||
|
||||
# unordered_dense
|
||||
AddJsonPackage(unordered-dense)
|
||||
|
||||
# FFMpeg
|
||||
if (YUZU_USE_EXTERNAL_FFMPEG OR YUZU_USE_BUNDLED_FFMPEG)
|
||||
add_subdirectory(ffmpeg)
|
||||
@@ -413,12 +401,10 @@ if (APPLE)
|
||||
# moltenvk
|
||||
if (NOT YUZU_USE_BUNDLED_MOLTENVK)
|
||||
find_library(MOLTENVK_LIBRARY MoltenVK)
|
||||
else()
|
||||
unset(MOLTENVK_LIBRARY)
|
||||
endif()
|
||||
|
||||
# TODO: kosmickrisp?
|
||||
if (NOT MOLTENVK_LIBRARY)
|
||||
if (NOT MOLTENVK_LIBRARY OR YUZU_USE_BUNDLED_MOLTENVK)
|
||||
AddJsonPackage(moltenvk)
|
||||
|
||||
set(MOLTENVK_LIBRARY "${moltenvk_SOURCE_DIR}/MoltenVK/dylib/macOS/libMoltenVK.dylib" CACHE STRING "" FORCE)
|
||||
|
||||
@@ -28,11 +28,14 @@
|
||||
"httplib": {
|
||||
"repo": "yhirose/cpp-httplib",
|
||||
"tag": "v%VERSION%",
|
||||
"hash": "e7a8877d489c97669a8ee536e1498575be921e558ed947253013fe6b67a49d4569eedd01f543caa70183b92d8ac0e8687d662a70d880954412e387317008a239",
|
||||
"git_version": "0.28.0",
|
||||
"hash": "a229e24cca4afe78e5c0aa2e482f15108ac34101fd8dbd927365f15e8c37dec4de38c5277d635017d692a5b320e1b929f8bfcc076f52b8e4dcdab8fe53bfdf2e",
|
||||
"git_version": "0.30.1",
|
||||
"find_args": "MODULE GLOBAL",
|
||||
"patches": [
|
||||
"0001-mingw.patch"
|
||||
],
|
||||
"options": [
|
||||
"HTTPLIB_REQUIRE_OPENSSL ON"
|
||||
]
|
||||
},
|
||||
"cpp-jwt": {
|
||||
@@ -48,23 +51,12 @@
|
||||
"0001-fix-missing-decl.patch"
|
||||
]
|
||||
},
|
||||
"xbyak_sun": {
|
||||
"package": "xbyak",
|
||||
"repo": "herumi/xbyak",
|
||||
"tag": "v%VERSION%",
|
||||
"hash": "b40dade90fb0e46a2bd52934f7ce461e37be931b571e58cbe2203bc08ed5b54c7ff1a29026c74c7f9805e4e3f6c9636deca528e6b4a8093ce7eae145218599f1",
|
||||
"git_version": "7.29",
|
||||
"bundled": true,
|
||||
"skip_updates": true
|
||||
},
|
||||
"xbyak": {
|
||||
"package": "xbyak",
|
||||
"repo": "herumi/xbyak",
|
||||
"tag": "v%VERSION%",
|
||||
"hash": "1042090405c426e339506c179d53e91d4d545ce9c9f53d8f797caa092d589f913a9bcb9c8f31c4c60870acb954c556e305fb6732c66bc3c8f1cd924f9172def9",
|
||||
"git_version": "7.22",
|
||||
"bundled": true,
|
||||
"skip_updates": true
|
||||
"hash": "ac333d7bea1d61865bebebb116201a58db431946aa2f11aa042ef5795c390ff30af4d6c90ed3b3d24443a1d430703b08f14fc13b2fa405c155a241456ed78a47",
|
||||
"git_version": "7.33.2"
|
||||
},
|
||||
"oaknut": {
|
||||
"repo": "eden-emulator/oaknut",
|
||||
@@ -91,23 +83,12 @@
|
||||
"unordered-dense": {
|
||||
"package": "unordered_dense",
|
||||
"repo": "martinus/unordered_dense",
|
||||
"tag": "v%VERSION%",
|
||||
"hash": "b98b5d4d96f8e0081b184d6c4c1181fae4e41723b54bed4296717d7f417348b48fad0bbcc664cac142b8c8a47e95aa57c1eb1cf6caa855fd782fad3e3ab99e5e",
|
||||
"sha": "7b55cab841",
|
||||
"hash": "d2106f6640f6bfb81755e4b8bfb64982e46ec4a507cacdb38f940123212ccf35a20b43c70c6f01d7bfb8c246d1a16f7845d8052971949cea9def1475e3fa02c8",
|
||||
"find_args": "CONFIG",
|
||||
"git_version": "4.8.1"
|
||||
},
|
||||
"mbedtls": {
|
||||
"package": "MbedTLS",
|
||||
"repo": "Mbed-TLS/mbedtls",
|
||||
"tag": "mbedtls-%VERSION%",
|
||||
"hash": "6671fb8fcaa832e5b115dfdce8f78baa6a4aea71f5c89a640583634cdee27aefe3bf4be075744da91f7c3ae5ea4e0c765c8fc3937b5cfd9ea73d87ef496524da",
|
||||
"version": "3",
|
||||
"git_version": "3.6.4",
|
||||
"artifact": "%TAG%.tar.bz2",
|
||||
"skip_updates": true,
|
||||
"bundled": true,
|
||||
"patches": [
|
||||
"0001-aesni-fix.patch",
|
||||
"0002-arm64-aes-fix.patch"
|
||||
"0001-avoid-memset-when-clearing-an-empty-table.patch"
|
||||
]
|
||||
},
|
||||
"enet": {
|
||||
@@ -118,15 +99,6 @@
|
||||
"git_version": "1.3.18",
|
||||
"find_args": "MODULE"
|
||||
},
|
||||
"vulkan-utility-headers": {
|
||||
"package": "VulkanUtilityLibraries",
|
||||
"repo": "scripts/VulkanUtilityHeaders",
|
||||
"tag": "%VERSION%",
|
||||
"git_version": "1.4.335",
|
||||
"artifact": "VulkanUtilityHeaders.tar.zst",
|
||||
"git_host": "git.crueter.xyz",
|
||||
"hash": "16dac0e6586702580c4279e4cd37ffe3cf909c93eb31b5069da7af36436d47b270a9cbaac953bb66c22ed12ed67ffa096688599267f307dfb62be1bc09f79833"
|
||||
},
|
||||
"spirv-tools": {
|
||||
"package": "SPIRV-Tools",
|
||||
"repo": "KhronosGroup/SPIRV-Tools",
|
||||
@@ -167,16 +139,16 @@
|
||||
"package": "SDL2",
|
||||
"name": "SDL2",
|
||||
"repo": "crueter-ci/SDL2",
|
||||
"version": "2.32.10-a65111bd2d",
|
||||
"version": "2.32.10-cf5dabd6ea",
|
||||
"min_version": "2.26.4"
|
||||
},
|
||||
"catch2": {
|
||||
"package": "Catch2",
|
||||
"repo": "catchorg/Catch2",
|
||||
"tag": "v%VERSION%",
|
||||
"hash": "a95495142f915d6e9c2a23e80fe360343e9097680066a2f9d3037a070ba5f81ee5559a0407cc9e972dc2afae325873f1fc7ea07a64012c0f01aac6e549f03e3f",
|
||||
"hash": "acb3f463a7404d6a3bce52e474075cdadf9bb241d93feaf147c182d756e5a2f8bd412f4658ca186d15ab8fed36fc587d79ec311f55642d8e4ded16df9e213656",
|
||||
"version": "3.0.1",
|
||||
"git_version": "3.11.0",
|
||||
"git_version": "3.12.0",
|
||||
"patches": [
|
||||
"0001-solaris-isnan-fix.patch"
|
||||
]
|
||||
@@ -201,7 +173,6 @@
|
||||
"repo": "libsdl-org/SDL",
|
||||
"tag": "release-%VERSION%",
|
||||
"hash": "d5622d6bb7266f7942a7b8ad43e8a22524893bf0c2ea1af91204838d9b78d32768843f6faa248757427b8404b8c6443776d4afa6b672cd8571a4e0c03a829383",
|
||||
"key": "generic",
|
||||
"bundled": true,
|
||||
"git_version": "2.32.10",
|
||||
"skip_updates": true
|
||||
@@ -211,7 +182,6 @@
|
||||
"repo": "libsdl-org/SDL",
|
||||
"sha": "cc016b0046",
|
||||
"hash": "b8d9873446cdb922387471df9968e078714683046674ef0d0edddf8e25da65a539a3bae83d635496b970237f90b07b36a69f8d7855d450de59311d6d6e8c3dbc",
|
||||
"key": "steamdeck",
|
||||
"bundled": true,
|
||||
"skip_updates": "true"
|
||||
},
|
||||
@@ -261,8 +231,8 @@
|
||||
},
|
||||
"ffmpeg": {
|
||||
"repo": "FFmpeg/FFmpeg",
|
||||
"sha": "5e56937b74",
|
||||
"hash": "9ab0457dcd6ce6359b5053c1662f57910d332f68ca0cca9d4134d858464840917027374de3d97e0863c3a7daaea2fe4f4cd17d1c6d8e7f740f4ad91e71c2932b",
|
||||
"sha": "c7b5f1537d",
|
||||
"hash": "ed177621176b3961bdcaa339187d3a7688c1c8b060b79c4bb0257cbc67ad7021ae5d5adca5303b45625abbbe3d9aafdd87ce777b8690ac295290d744c875489a",
|
||||
"bundled": true
|
||||
},
|
||||
"ffmpeg-ci": {
|
||||
@@ -270,7 +240,7 @@
|
||||
"package": "FFmpeg",
|
||||
"name": "ffmpeg",
|
||||
"repo": "crueter-ci/FFmpeg",
|
||||
"version": "8.0.1-5e56937b74",
|
||||
"version": "8.0.1-c7b5f1537d",
|
||||
"min_version": "4.1"
|
||||
},
|
||||
"tzdb": {
|
||||
@@ -281,5 +251,26 @@
|
||||
"tag": "%VERSION%",
|
||||
"hash": "dc37a189a44ce8b5c988ca550582431a6c7eadfd3c6e709bee6277116ee803e714333e85c9e6cbb5c69346a14d6f2cc7ed96e8aa09cc5fb8a89f945059651db6",
|
||||
"version": "121125"
|
||||
},
|
||||
"vulkan-headers": {
|
||||
"repo": "KhronosGroup/Vulkan-Headers",
|
||||
"package": "VulkanHeaders",
|
||||
"version": "1.4.317",
|
||||
"hash": "26e0ad8fa34ab65a91ca62ddc54cc4410d209a94f64f2817dcdb8061dc621539a4262eab6387e9b9aa421db3dbf2cf8e2a4b041b696d0d03746bae1f25191272",
|
||||
"git_version": "1.4.342",
|
||||
"tag": "v%VERSION%"
|
||||
},
|
||||
"vulkan-utility-libraries": {
|
||||
"repo": "KhronosGroup/Vulkan-Utility-Libraries",
|
||||
"package": "VulkanUtilityLibraries",
|
||||
"hash": "8147370f964fd82c315d6bb89adeda30186098427bf3efaa641d36282d42a263f31e96e4586bfd7ae0410ff015379c19aa4512ba160630444d3d8553afd1ec14",
|
||||
"git_version": "1.4.342",
|
||||
"tag": "v%VERSION%"
|
||||
},
|
||||
"frozen": {
|
||||
"package": "frozen",
|
||||
"repo": "serge-sans-paille/frozen",
|
||||
"sha": "61dce5ae18",
|
||||
"hash": "b8dfe741c82bc178dfc9749d4ab5a130cee718d9ee7b71d9b547cf5f7f23027ed0152ad250012a8546399fcc1e12187efc68d89d6731256c4d2df7d04eef8d5c"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
@@ -33,7 +33,7 @@ endif()
|
||||
|
||||
if(NOT YUZU_TZDB_PATH STREQUAL "")
|
||||
set(NX_TZDB_BASE_DIR "${YUZU_TZDB_PATH}")
|
||||
elseif (MSVC AND NOT CXX_CLANG AND YUZU_ENABLE_LTO)
|
||||
elseif (MSVC AND NOT CXX_CLANG AND ENABLE_LTO)
|
||||
# TODO(crueter): boot up the windows vm
|
||||
set(NX_TZDB_VERSION "250725")
|
||||
set(NX_TZDB_ARCHIVE "${CPM_SOURCE_CACHE}/nx_tzdb/${NX_TZDB_VERSION}.zip")
|
||||
|
||||
@@ -9,7 +9,7 @@ pkgs.mkShellNoCC {
|
||||
# libraries
|
||||
openssl boost fmt nlohmann_json lz4 zlib zstd
|
||||
enet libopus vulkan-headers vulkan-utility-libraries
|
||||
spirv-tools spirv-headers vulkan-loader unzip mbedtls
|
||||
spirv-tools spirv-headers vulkan-loader unzip
|
||||
glslang python3 httplib cpp-jwt ffmpeg-headless
|
||||
libusb1 cubeb
|
||||
# eden
|
||||
@@ -20,4 +20,4 @@ pkgs.mkShellNoCC {
|
||||
# optional components
|
||||
discord-rpc gamemode
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,10 @@ if (MSVC AND NOT CXX_CLANG)
|
||||
/wd4324 # 'struct_name': structure was padded due to __declspec(align())
|
||||
/wd4201 # nonstandard extension used : nameless struct/union
|
||||
/wd4702 # unreachable code (when used with LTO)
|
||||
|
||||
$<$<CONFIG:Release>:/GS-> # No stack buffer overflow checks
|
||||
/Gy # Enable function level linking
|
||||
/GR- # Disable run time type information
|
||||
)
|
||||
|
||||
if (NOT CXX_CLANG)
|
||||
@@ -108,15 +112,14 @@ if (MSVC AND NOT CXX_CLANG)
|
||||
add_compile_options(/QIntel-jcc-erratum)
|
||||
endif()
|
||||
|
||||
# /GS- - No stack buffer overflow checks
|
||||
add_compile_options("$<$<CONFIG:Release>:/GS->")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG /MANIFEST:NO" CACHE STRING "" FORCE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE)
|
||||
else()
|
||||
if (NOT MSVC)
|
||||
add_compile_options(
|
||||
-fwrapv
|
||||
-fno-rtti # Disable RTTI
|
||||
-pipe
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -232,7 +235,7 @@ if (YUZU_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if (ENABLE_SDL2 AND YUZU_CMD)
|
||||
if (YUZU_CMD)
|
||||
add_subdirectory(yuzu_cmd)
|
||||
set_target_properties(yuzu-cmd PROPERTIES OUTPUT_NAME "eden-cli")
|
||||
endif()
|
||||
|
||||
@@ -79,9 +79,7 @@ android {
|
||||
arguments.addAll(
|
||||
listOf(
|
||||
"-DENABLE_QT=0", // Don't use QT
|
||||
"-DENABLE_SDL2=0", // Don't use SDL
|
||||
"-DENABLE_WEB_SERVICE=1", // Enable web service
|
||||
"-DENABLE_OPENSSL=ON",
|
||||
"-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work
|
||||
"-DYUZU_USE_CPM=ON",
|
||||
"-DCPMUTIL_FORCE_BUNDLED=ON",
|
||||
|
||||
@@ -152,6 +152,10 @@ object NativeLibrary {
|
||||
|
||||
external fun surfaceDestroyed()
|
||||
|
||||
external fun getAppletCaptureBuffer(): ByteArray
|
||||
external fun getAppletCaptureWidth(): Int
|
||||
external fun getAppletCaptureHeight(): Int
|
||||
|
||||
/**
|
||||
* Unpauses emulation from a paused state.
|
||||
*/
|
||||
@@ -203,6 +207,24 @@ object NativeLibrary {
|
||||
|
||||
external fun getDebugKnobAt(index: Int): Boolean
|
||||
|
||||
/**
|
||||
* Set the current speed limit to the configured turbo speed.
|
||||
*/
|
||||
external fun setTurboSpeedLimit(enabled: Boolean)
|
||||
|
||||
/**
|
||||
* Set the current speed limit to the configured slow speed.
|
||||
*/
|
||||
external fun setSlowSpeedLimit(enabled: Boolean)
|
||||
|
||||
/**
|
||||
* Set the current speed limit to the configured standard speed.
|
||||
*/
|
||||
external fun setStandardSpeedLimit(enabled: Boolean)
|
||||
|
||||
external fun isTurboMode(): Boolean
|
||||
external fun isSlowMode(): Boolean
|
||||
|
||||
/**
|
||||
* Returns Vulkan driver version / API version / GPU model
|
||||
*/
|
||||
@@ -585,6 +607,12 @@ object NativeLibrary {
|
||||
*/
|
||||
external fun addFileToFilesystemProvider(path: String)
|
||||
|
||||
/**
|
||||
* Adds a game-folder file to the manual filesystem provider, respecting the internal gate for
|
||||
* game-folder external-content mounting.
|
||||
*/
|
||||
external fun addGameFolderFileToFilesystemProvider(path: String)
|
||||
|
||||
/**
|
||||
* Clears all files added to the manual filesystem provider in our EmulationSession instance
|
||||
*/
|
||||
@@ -614,4 +642,23 @@ object NativeLibrary {
|
||||
* Updates the device power state to global variables
|
||||
*/
|
||||
external fun updatePowerState(percentage: Int, isCharging: Boolean, hasBattery: Boolean)
|
||||
|
||||
/**
|
||||
* Profile manager native calls
|
||||
*/
|
||||
external fun getAllUsers(): Array<String>?
|
||||
external fun getUserUsername(uuid: String): String?
|
||||
external fun getUserCount(): Long
|
||||
external fun canCreateUser(): Boolean
|
||||
external fun createUser(uuid: String, username: String): Boolean
|
||||
external fun updateUserUsername(uuid: String, username: String): Boolean
|
||||
external fun removeUser(uuid: String): Boolean
|
||||
external fun getCurrentUser(): String?
|
||||
external fun setCurrentUser(uuid: String): Boolean
|
||||
external fun getUserImagePath(uuid: String): String?
|
||||
external fun saveUserImage(uuid: String, imagePath: String): Boolean
|
||||
external fun reloadProfiles()
|
||||
external fun getFirmwareAvatarCount(): Int
|
||||
external fun getFirmwareAvatarImage(index: Int): ByteArray?
|
||||
external fun getDefaultAccountBackupJpeg(): ByteArray
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
@@ -24,6 +24,7 @@ import org.yuzu.yuzu_emu.utils.DocumentsTree
|
||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||
import org.yuzu.yuzu_emu.utils.Log
|
||||
import org.yuzu.yuzu_emu.utils.PowerStateUpdater
|
||||
import org.yuzu.yuzu_emu.utils.ControllerNavigationGlobalHook
|
||||
import java.util.Locale
|
||||
|
||||
fun Context.getPublicFilesDir(): File = getExternalFilesDir(null) ?: filesDir
|
||||
@@ -72,6 +73,7 @@ class YuzuApplication : Application() {
|
||||
NativeLibrary.logDeviceInfo()
|
||||
PowerStateUpdater.start()
|
||||
Log.logDeviceInfo()
|
||||
ControllerNavigationGlobalHook.install(this)
|
||||
|
||||
createNotificationChannels()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
@@ -204,9 +204,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
nfcReader.stopScanning()
|
||||
stopMotionSensorListener()
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
@@ -339,6 +339,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
|
||||
}
|
||||
|
||||
override fun onSensorChanged(event: SensorEvent) {
|
||||
if (!NativeLibrary.isRunning() || NativeLibrary.isPaused()) {
|
||||
return
|
||||
}
|
||||
|
||||
val rotation = this.display?.rotation
|
||||
if (rotation == Surface.ROTATION_90) {
|
||||
flipMotionOrientation = true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
@@ -10,6 +10,7 @@ import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemAddonBinding
|
||||
import org.yuzu.yuzu_emu.model.Patch
|
||||
import org.yuzu.yuzu_emu.model.PatchType
|
||||
import org.yuzu.yuzu_emu.model.AddonViewModel
|
||||
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
|
||||
|
||||
@@ -31,7 +32,12 @@ class AddonAdapter(val addonViewModel: AddonViewModel) :
|
||||
binding.addonSwitch.isChecked = model.enabled
|
||||
|
||||
binding.addonSwitch.setOnCheckedChangeListener { _, checked ->
|
||||
model.enabled = checked
|
||||
if (PatchType.from(model.type) == PatchType.Update && checked) {
|
||||
addonViewModel.enableOnlyThisUpdate(model)
|
||||
notifyDataSetChanged()
|
||||
} else {
|
||||
model.enabled = checked
|
||||
}
|
||||
}
|
||||
|
||||
val deleteAction = {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.adapters
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.yuzu.yuzu_emu.databinding.ItemFirmwareAvatarBinding
|
||||
|
||||
class FirmwareAvatarAdapter(
|
||||
private val avatars: List<Bitmap>,
|
||||
private val onAvatarSelected: (Bitmap) -> Unit
|
||||
) : RecyclerView.Adapter<FirmwareAvatarAdapter.AvatarViewHolder>() {
|
||||
|
||||
private var selectedPosition = -1
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AvatarViewHolder {
|
||||
val binding = ItemFirmwareAvatarBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
return AvatarViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: AvatarViewHolder, position: Int) {
|
||||
holder.bind(avatars[position], position == selectedPosition)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = avatars.size
|
||||
|
||||
inner class AvatarViewHolder(
|
||||
private val binding: ItemFirmwareAvatarBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(avatar: Bitmap, isSelected: Boolean) {
|
||||
binding.imageAvatar.setImageBitmap(avatar)
|
||||
binding.root.isChecked = isSelected
|
||||
|
||||
binding.root.setOnClickListener {
|
||||
val previousSelected = selectedPosition
|
||||
selectedPosition = bindingAdapterPosition
|
||||
|
||||
if (previousSelected != -1) {
|
||||
notifyItemChanged(previousSelected)
|
||||
}
|
||||
notifyItemChanged(selectedPosition)
|
||||
|
||||
onAvatarSelected(avatar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -7,8 +10,10 @@ import android.net.Uri
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.databinding.CardFolderBinding
|
||||
import org.yuzu.yuzu_emu.fragments.GameFolderPropertiesDialogFragment
|
||||
import org.yuzu.yuzu_emu.model.DirectoryType
|
||||
import org.yuzu.yuzu_emu.model.GameDir
|
||||
import org.yuzu.yuzu_emu.model.GamesViewModel
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
|
||||
@@ -31,6 +36,12 @@ class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesVie
|
||||
path.text = Uri.parse(model.uriString).path
|
||||
path.marquee()
|
||||
|
||||
// Set type indicator, shows below folder name, to see if DLC or Games
|
||||
typeIndicator.text = when (model.type) {
|
||||
DirectoryType.GAME -> activity.getString(R.string.games)
|
||||
DirectoryType.EXTERNAL_CONTENT -> activity.getString(R.string.external_content)
|
||||
}
|
||||
|
||||
buttonEdit.setOnClickListener {
|
||||
GameFolderPropertiesDialogFragment.newInstance(model)
|
||||
.show(
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.adapters
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.AsyncListDiffer
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemProfileBinding
|
||||
import org.yuzu.yuzu_emu.model.UserProfile
|
||||
import java.io.File
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
|
||||
class ProfileAdapter(
|
||||
private val onProfileClick: (UserProfile) -> Unit,
|
||||
private val onEditClick: (UserProfile) -> Unit,
|
||||
private val onDeleteClick: (UserProfile) -> Unit
|
||||
) : RecyclerView.Adapter<ProfileAdapter.ProfileViewHolder>() {
|
||||
|
||||
private var currentUserUUID: String = ""
|
||||
|
||||
private val differ = AsyncListDiffer(this, object : DiffUtil.ItemCallback<UserProfile>() {
|
||||
override fun areItemsTheSame(oldItem: UserProfile, newItem: UserProfile): Boolean {
|
||||
return oldItem.uuid == newItem.uuid
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: UserProfile, newItem: UserProfile): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
})
|
||||
|
||||
fun submitList(list: List<UserProfile>) {
|
||||
differ.submitList(list)
|
||||
}
|
||||
|
||||
fun setCurrentUser(uuid: String) {
|
||||
currentUserUUID = uuid
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProfileViewHolder {
|
||||
val binding = ListItemProfileBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
return ProfileViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ProfileViewHolder, position: Int) {
|
||||
holder.bind(differ.currentList[position])
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = differ.currentList.size
|
||||
|
||||
inner class ProfileViewHolder(private val binding: ListItemProfileBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(profile: UserProfile) {
|
||||
binding.textUsername.text = profile.username
|
||||
binding.textUuid.text = formatUUID(profile.uuid)
|
||||
|
||||
val imageFile = File(profile.imagePath)
|
||||
if (imageFile.exists()) {
|
||||
val bitmap = BitmapFactory.decodeFile(profile.imagePath)
|
||||
binding.imageAvatar.setImageBitmap(bitmap)
|
||||
} else {
|
||||
val jpegData = NativeLibrary.getDefaultAccountBackupJpeg()
|
||||
val bitmap = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.size)
|
||||
binding.imageAvatar.setImageBitmap(bitmap)
|
||||
}
|
||||
|
||||
if (profile.uuid == currentUserUUID) {
|
||||
binding.checkContainer.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.checkContainer.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.root.setOnClickListener {
|
||||
onProfileClick(profile)
|
||||
}
|
||||
|
||||
binding.buttonEdit.setOnClickListener {
|
||||
onEditClick(profile)
|
||||
}
|
||||
|
||||
binding.buttonDelete.setOnClickListener {
|
||||
onDeleteClick(profile)
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatUUID(uuid: String): String {
|
||||
if (uuid.length != 32) return uuid
|
||||
return buildString {
|
||||
append(uuid.substring(0, 8))
|
||||
append("-")
|
||||
append(uuid.substring(8, 12))
|
||||
append("-")
|
||||
append(uuid.substring(12, 16))
|
||||
append("-")
|
||||
append(uuid.substring(16, 20))
|
||||
append("-")
|
||||
append(uuid.substring(20, 32))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import android.widget.RadioGroup
|
||||
import android.widget.TextView
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.materialswitch.MaterialSwitch
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.YuzuApplication
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
@@ -22,14 +23,6 @@ import org.yuzu.yuzu_emu.features.settings.model.AbstractShortSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
||||
|
||||
class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||
// Kinda a crappy workaround to get a title from setting keys
|
||||
// Idk how to do this witthout hardcoding every single one
|
||||
private fun getSettingTitle(settingKey: String): String {
|
||||
return settingKey.replace("_", " ").split(" ")
|
||||
.joinToString(" ") { it.replaceFirstChar { c -> c.uppercase() } }
|
||||
|
||||
}
|
||||
|
||||
private fun saveSettings() {
|
||||
if (emulationFragment.shouldUseCustom) {
|
||||
NativeConfig.savePerGameConfig()
|
||||
@@ -60,6 +53,7 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||
// settings
|
||||
|
||||
fun addIntSetting(
|
||||
name: Int,
|
||||
container: ViewGroup,
|
||||
setting: IntSetting,
|
||||
namesArrayId: Int,
|
||||
@@ -73,7 +67,7 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||
val expandIcon = itemView.findViewById<android.widget.ImageView>(R.id.expand_icon)
|
||||
val radioGroup = itemView.findViewById<RadioGroup>(R.id.radio_group)
|
||||
|
||||
titleView.text = getSettingTitle(setting.key)
|
||||
titleView.text = YuzuApplication.appContext.getString(name)
|
||||
|
||||
val names = emulationFragment.resources.getStringArray(namesArrayId)
|
||||
val values = emulationFragment.resources.getIntArray(valuesArrayId)
|
||||
@@ -115,6 +109,8 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||
}
|
||||
|
||||
fun addBooleanSetting(
|
||||
name: Int,
|
||||
|
||||
container: ViewGroup,
|
||||
setting: BooleanSetting
|
||||
) {
|
||||
@@ -125,7 +121,7 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||
val titleView = itemView.findViewById<TextView>(R.id.switch_title)
|
||||
val switchView = itemView.findViewById<com.google.android.material.materialswitch.MaterialSwitch>(R.id.setting_switch)
|
||||
|
||||
titleView.text = getSettingTitle(setting.key)
|
||||
titleView.text = YuzuApplication.appContext.getString(name)
|
||||
switchContainer.visibility = View.VISIBLE
|
||||
switchView.isChecked = setting.getBoolean()
|
||||
|
||||
@@ -140,7 +136,41 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||
container.addView(itemView)
|
||||
}
|
||||
|
||||
fun addCustomToggle(
|
||||
name: Int,
|
||||
isChecked: Boolean,
|
||||
isEnabled: Boolean,
|
||||
|
||||
container: ViewGroup,
|
||||
callback: (Boolean) -> Unit
|
||||
): MaterialSwitch? {
|
||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
||||
val itemView = inflater.inflate(R.layout.item_quick_settings_menu, container, false)
|
||||
|
||||
val switchContainer = itemView.findViewById<ViewGroup>(R.id.switch_container)
|
||||
val titleView = itemView.findViewById<TextView>(R.id.switch_title)
|
||||
val switchView = itemView.findViewById<MaterialSwitch>(R.id.setting_switch)
|
||||
|
||||
titleView.text = YuzuApplication.appContext.getString(name)
|
||||
switchContainer.visibility = View.VISIBLE
|
||||
|
||||
switchView.isChecked = isChecked
|
||||
|
||||
switchView.setOnCheckedChangeListener { _, checked ->
|
||||
callback(checked)
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
switchContainer.setOnClickListener {
|
||||
switchView.toggle()
|
||||
}
|
||||
container.addView(itemView)
|
||||
|
||||
return switchView
|
||||
}
|
||||
|
||||
fun addSliderSetting(
|
||||
name: Int,
|
||||
container: ViewGroup,
|
||||
setting: AbstractSetting,
|
||||
minValue: Int = 0,
|
||||
@@ -156,7 +186,7 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||
val slider = itemView.findViewById<com.google.android.material.slider.Slider>(R.id.setting_slider)
|
||||
|
||||
|
||||
titleView.text = getSettingTitle(setting.key)
|
||||
titleView.text = YuzuApplication.appContext.getString(name)
|
||||
sliderContainer.visibility = View.VISIBLE
|
||||
|
||||
slider.valueFrom = minValue.toFloat()
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.fetcher
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
class SpacingItemDecoration(private val spacing: Int) : RecyclerView.ItemDecoration() {
|
||||
@@ -15,8 +16,20 @@ class SpacingItemDecoration(private val spacing: Int) : RecyclerView.ItemDecorat
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
outRect.bottom = spacing
|
||||
if (parent.getChildAdapterPosition(view) == 0) {
|
||||
|
||||
val position = parent.getChildAdapterPosition(view)
|
||||
if (position == RecyclerView.NO_POSITION) return
|
||||
|
||||
if (position == 0) {
|
||||
outRect.top = spacing
|
||||
return
|
||||
}
|
||||
|
||||
// If the item is in the first row, but NOT in first column add top spacing as well
|
||||
val layoutManager = parent.layoutManager
|
||||
if (layoutManager is GridLayoutManager && layoutManager.spanSizeLookup.getSpanGroupIndex(position, layoutManager.spanCount) == 0) {
|
||||
outRect.top = spacing
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,15 +24,22 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||
RENDERER_FORCE_MAX_CLOCK("force_max_clock"),
|
||||
RENDERER_ASYNCHRONOUS_SHADERS("use_asynchronous_shaders"),
|
||||
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
|
||||
ENABLE_BUFFER_HISTORY("enable_buffer_history"),
|
||||
USE_OPTIMIZED_VERTEX_BUFFERS("use_optimized_vertex_buffers"),
|
||||
SYNC_MEMORY_OPERATIONS("sync_memory_operations"),
|
||||
BUFFER_REORDER_DISABLE("disable_buffer_reorder"),
|
||||
RENDERER_DEBUG("debug"),
|
||||
RENDERER_PATCH_OLD_QCOM_DRIVERS("patch_old_qcom_drivers"),
|
||||
RENDERER_VERTEX_INPUT_DYNAMIC_STATE("vertex_input_dynamic_state"),
|
||||
RENDERER_DESCRIPTOR_INDEXING("descriptor_indexing"),
|
||||
RENDERER_SAMPLE_SHADING("sample_shading"),
|
||||
GPU_UNSWIZZLE_ENABLED("gpu_unswizzle_enabled"),
|
||||
PICTURE_IN_PICTURE("picture_in_picture"),
|
||||
USE_CUSTOM_RTC("custom_rtc_enabled"),
|
||||
BLACK_BACKGROUNDS("black_backgrounds"),
|
||||
INVERT_CONFIRM_BACK_CONTROLLER_BUTTONS("invert_confirm_back_controller_buttons"),
|
||||
|
||||
ENABLE_FOLDER_BUTTON("enable_folder_button"),
|
||||
ENABLE_QLAUNCH_BUTTON("enable_qlaunch_button"),
|
||||
|
||||
ENABLE_UPDATE_CHECKS("enable_update_checks"),
|
||||
JOYSTICK_REL_CENTER("joystick_rel_center"),
|
||||
@@ -67,8 +74,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||
SHOW_SHADERS_BUILDING("show_shaders_building"),
|
||||
|
||||
DEBUG_FLUSH_BY_LINE("flush_line"),
|
||||
USE_LRU_CACHE("use_lru_cache"),
|
||||
|
||||
DONT_SHOW_DRIVER_SHADER_WARNING("dont_show_driver_shader_warning"),
|
||||
ENABLE_OVERLAY("enable_overlay"),
|
||||
|
||||
@@ -77,8 +82,9 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||
GPU_LOG_VULKAN_CALLS("gpu_log_vulkan_calls"),
|
||||
GPU_LOG_SHADER_DUMPS("gpu_log_shader_dumps"),
|
||||
GPU_LOG_MEMORY_TRACKING("gpu_log_memory_tracking"),
|
||||
GPU_LOG_DRIVER_DEBUG("gpu_log_driver_debug");
|
||||
GPU_LOG_DRIVER_DEBUG("gpu_log_driver_debug"),
|
||||
|
||||
ENABLE_QUICK_SETTINGS("enable_quick_settings");
|
||||
|
||||
// external fun isFrameSkippingEnabled(): Boolean
|
||||
external fun isFrameInterpolationEnabled(): Boolean
|
||||
|
||||
@@ -29,10 +29,12 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
||||
|
||||
RENDERER_DYNA_STATE("dyna_state"),
|
||||
DMA_ACCURACY("dma_accuracy"),
|
||||
FRAME_PACING_MODE("frame_pacing_mode"),
|
||||
AUDIO_OUTPUT_ENGINE("output_engine"),
|
||||
MAX_ANISOTROPY("max_anisotropy"),
|
||||
THEME("theme"),
|
||||
THEME_MODE("theme_mode"),
|
||||
STATIC_THEME_COLOR("static_theme_color"),
|
||||
APP_LANGUAGE("app_language"),
|
||||
OVERLAY_SCALE("control_scale"),
|
||||
OVERLAY_OPACITY("control_opacity"),
|
||||
@@ -67,7 +69,6 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
||||
MY_PAGE_APPLET("my_page_applet_mode"),
|
||||
INPUT_OVERLAY_AUTO_HIDE("input_overlay_auto_hide"),
|
||||
OVERLAY_GRID_SIZE("overlay_grid_size"),
|
||||
DEBUG_KNOBS("debug_knobs"),
|
||||
GPU_LOG_RING_BUFFER_SIZE("gpu_log_ring_buffer_size")
|
||||
;
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -6,7 +9,11 @@ package org.yuzu.yuzu_emu.features.settings.model
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
|
||||
enum class ShortSetting(override val key: String) : AbstractShortSetting {
|
||||
RENDERER_SPEED_LIMIT("speed_limit");
|
||||
RENDERER_SPEED_LIMIT("speed_limit"),
|
||||
RENDERER_TURBO_SPEED_LIMIT("turbo_speed_limit"),
|
||||
RENDERER_SLOW_SPEED_LIMIT("slow_speed_limit"),
|
||||
DEBUG_KNOBS("debug_knobs")
|
||||
;
|
||||
|
||||
override fun getShort(needsGlobal: Boolean): Short = NativeConfig.getShort(key, needsGlobal)
|
||||
|
||||
@@ -22,4 +29,4 @@ enum class ShortSetting(override val key: String) : AbstractShortSetting {
|
||||
override fun getValueAsString(needsGlobal: Boolean): String = getShort(needsGlobal).toString()
|
||||
|
||||
override fun reset() = NativeConfig.setShort(key, defaultValue)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||
|
||||
import androidx.annotation.ArrayRes
|
||||
import androidx.annotation.StringRes
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||
|
||||
class GpuUnswizzleSetting(
|
||||
@StringRes titleId: Int = 0,
|
||||
titleString: String = "",
|
||||
@StringRes descriptionId: Int = 0,
|
||||
descriptionString: String = "",
|
||||
@ArrayRes val textureSizeChoicesId: Int,
|
||||
@ArrayRes val textureSizeValuesId: Int,
|
||||
@ArrayRes val streamSizeChoicesId: Int,
|
||||
@ArrayRes val streamSizeValuesId: Int,
|
||||
@ArrayRes val chunkSizeChoicesId: Int,
|
||||
@ArrayRes val chunkSizeValuesId: Int
|
||||
) : SettingsItem(
|
||||
object : AbstractSetting {
|
||||
override val key: String = SettingsItem.GPU_UNSWIZZLE_COMBINED
|
||||
override val defaultValue: Any = false
|
||||
override val isSaveable = true
|
||||
override val isRuntimeModifiable = true
|
||||
override val isSwitchable = true
|
||||
override fun getValueAsString(needsGlobal: Boolean): String = "combined"
|
||||
override fun reset() {
|
||||
BooleanSetting.GPU_UNSWIZZLE_ENABLED.reset()
|
||||
IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.reset()
|
||||
IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.reset()
|
||||
IntSetting.GPU_UNSWIZZLE_CHUNK_SIZE.reset()
|
||||
}
|
||||
},
|
||||
titleId,
|
||||
titleString,
|
||||
descriptionId,
|
||||
descriptionString
|
||||
) {
|
||||
override val type = SettingsItem.TYPE_GPU_UNSWIZZLE
|
||||
|
||||
// Check if GPU unswizzle is enabled via the dedicated boolean setting
|
||||
fun isEnabled(needsGlobal: Boolean = false): Boolean =
|
||||
BooleanSetting.GPU_UNSWIZZLE_ENABLED.getBoolean(needsGlobal)
|
||||
|
||||
fun setEnabled(value: Boolean) =
|
||||
BooleanSetting.GPU_UNSWIZZLE_ENABLED.setBoolean(value)
|
||||
|
||||
fun enable() = setEnabled(true)
|
||||
|
||||
fun disable() = setEnabled(false)
|
||||
|
||||
fun getTextureSize(needsGlobal: Boolean = false): Int =
|
||||
IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.getInt(needsGlobal)
|
||||
|
||||
fun setTextureSize(value: Int) =
|
||||
IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.setInt(value)
|
||||
|
||||
fun getStreamSize(needsGlobal: Boolean = false): Int =
|
||||
IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.getInt(needsGlobal)
|
||||
|
||||
fun setStreamSize(value: Int) =
|
||||
IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.setInt(value)
|
||||
|
||||
fun getChunkSize(needsGlobal: Boolean = false): Int =
|
||||
IntSetting.GPU_UNSWIZZLE_CHUNK_SIZE.getInt(needsGlobal)
|
||||
|
||||
fun setChunkSize(value: Int) =
|
||||
IntSetting.GPU_UNSWIZZLE_CHUNK_SIZE.setInt(value)
|
||||
|
||||
fun reset() = setting.reset()
|
||||
}
|
||||
@@ -60,6 +60,11 @@ abstract class SettingsItem(
|
||||
return NativeInput.getStyleIndex(0) != NpadStyleIndex.Handheld
|
||||
}
|
||||
|
||||
// Can't edit enable_qlaunch_button if firmware is not available
|
||||
if (setting.key == BooleanSetting.ENABLE_QLAUNCH_BUTTON.key) {
|
||||
return NativeLibrary.isFirmwareAvailable()
|
||||
}
|
||||
|
||||
// Can't edit settings that aren't saveable in per-game config even if they are switchable
|
||||
if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) {
|
||||
return false
|
||||
@@ -99,8 +104,10 @@ abstract class SettingsItem(
|
||||
const val TYPE_SPINBOX = 12
|
||||
const val TYPE_LAUNCHABLE = 13
|
||||
const val TYPE_PATH = 14
|
||||
const val TYPE_GPU_UNSWIZZLE = 15
|
||||
|
||||
const val FASTMEM_COMBINED = "fastmem_combined"
|
||||
const val GPU_UNSWIZZLE_COMBINED = "gpu_unswizzle_combined"
|
||||
|
||||
val emptySetting = object : AbstractSetting {
|
||||
override val key: String = ""
|
||||
@@ -118,13 +125,6 @@ abstract class SettingsItem(
|
||||
// List of all general
|
||||
val settingsItems = HashMap<String, SettingsItem>().apply {
|
||||
put(StringInputSetting(StringSetting.DEVICE_NAME, titleId = R.string.device_name))
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.USE_LRU_CACHE,
|
||||
titleId = R.string.use_lru_cache,
|
||||
descriptionId = R.string.use_lru_cache_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.RENDERER_USE_SPEED_LIMIT,
|
||||
@@ -143,10 +143,9 @@ abstract class SettingsItem(
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
|
||||
BooleanSetting.RENDERER_VERTEX_INPUT_DYNAMIC_STATE,
|
||||
titleId = R.string.vertex_input_dynamic_state,
|
||||
descriptionId = R.string.vertex_input_dynamic_state_description
|
||||
BooleanSetting.RENDERER_DESCRIPTOR_INDEXING,
|
||||
titleId = R.string.descriptor_indexing,
|
||||
descriptionId = R.string.descriptor_indexing_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
@@ -167,6 +166,26 @@ abstract class SettingsItem(
|
||||
units = "%"
|
||||
)
|
||||
)
|
||||
put(
|
||||
SliderSetting(
|
||||
ShortSetting.RENDERER_TURBO_SPEED_LIMIT,
|
||||
titleId = R.string.turbo_speed_limit,
|
||||
descriptionId = R.string.turbo_speed_limit_description,
|
||||
min = 1,
|
||||
max = 400,
|
||||
units = "%"
|
||||
)
|
||||
)
|
||||
put(
|
||||
SliderSetting(
|
||||
ShortSetting.RENDERER_SLOW_SPEED_LIMIT,
|
||||
titleId = R.string.slow_speed_limit,
|
||||
descriptionId = R.string.slow_speed_limit_description,
|
||||
min = 1,
|
||||
max = 400,
|
||||
units = "%"
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.CPU_BACKEND,
|
||||
@@ -316,15 +335,6 @@ abstract class SettingsItem(
|
||||
valuesId = R.array.astcDecodingMethodValues
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.RENDERER_ASTC_RECOMPRESSION,
|
||||
titleId = R.string.astc_recompression,
|
||||
descriptionId = R.string.astc_recompression_description,
|
||||
choicesId = R.array.astcRecompressionMethodNames,
|
||||
valuesId = R.array.astcRecompressionMethodValues
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.RENDERER_VRAM_USAGE_MODE,
|
||||
@@ -345,6 +355,13 @@ abstract class SettingsItem(
|
||||
warningMessage = R.string.warning_resolution
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.INVERT_CONFIRM_BACK_CONTROLLER_BUTTONS,
|
||||
titleId = R.string.invert_confirm_back_controller_buttons,
|
||||
descriptionId = R.string.invert_confirm_back_controller_buttons_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SHOW_INPUT_OVERLAY,
|
||||
@@ -673,6 +690,18 @@ abstract class SettingsItem(
|
||||
valuesId = R.array.gpuSwizzleChunkValues
|
||||
)
|
||||
)
|
||||
put(
|
||||
GpuUnswizzleSetting(
|
||||
titleId = R.string.gpu_unswizzle_settings,
|
||||
descriptionId = R.string.gpu_unswizzle_settings_description,
|
||||
textureSizeChoicesId = R.array.gpuTextureSizeSwizzleEntries,
|
||||
textureSizeValuesId = R.array.gpuTextureSizeSwizzleValues,
|
||||
streamSizeChoicesId = R.array.gpuSwizzleEntries,
|
||||
streamSizeValuesId = R.array.gpuSwizzleValues,
|
||||
chunkSizeChoicesId = R.array.gpuSwizzleChunkEntries,
|
||||
chunkSizeValuesId = R.array.gpuSwizzleChunkValues
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.FAST_CPU_TIME,
|
||||
@@ -727,6 +756,20 @@ abstract class SettingsItem(
|
||||
descriptionId = R.string.renderer_reactive_flushing_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.ENABLE_BUFFER_HISTORY,
|
||||
titleId = R.string.enable_buffer_history,
|
||||
descriptionId = R.string.enable_buffer_history_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS,
|
||||
titleId = R.string.use_optimized_vertex_buffers,
|
||||
descriptionId = R.string.use_optimized_vertex_buffers_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SYNC_MEMORY_OPERATIONS,
|
||||
@@ -781,6 +824,27 @@ abstract class SettingsItem(
|
||||
descriptionId = R.string.enable_update_checks_description,
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.ENABLE_QUICK_SETTINGS,
|
||||
titleId = R.string.enable_quick_settings,
|
||||
descriptionId = R.string.enable_quick_settings_description,
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.ENABLE_FOLDER_BUTTON,
|
||||
titleId = R.string.enable_folder_button,
|
||||
descriptionId = R.string.enable_folder_button_description,
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.ENABLE_QLAUNCH_BUTTON,
|
||||
titleId = R.string.enable_qlaunch_button,
|
||||
descriptionId = R.string.enable_qlaunch_button_description,
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.APP_LANGUAGE,
|
||||
@@ -814,7 +878,7 @@ abstract class SettingsItem(
|
||||
)
|
||||
put(
|
||||
SpinBoxSetting(
|
||||
IntSetting.DEBUG_KNOBS,
|
||||
ShortSetting.DEBUG_KNOBS,
|
||||
titleId = R.string.debug_knobs,
|
||||
descriptionId = R.string.debug_knobs_description,
|
||||
valueHint = R.string.debug_knobs_hint,
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.databinding.DialogGpuUnswizzleBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.GpuUnswizzleSetting
|
||||
|
||||
class GpuUnswizzleDialogFragment : DialogFragment() {
|
||||
private var position = 0
|
||||
private val settingsViewModel: SettingsViewModel by activityViewModels()
|
||||
private lateinit var binding: DialogGpuUnswizzleBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
position = requireArguments().getInt(POSITION)
|
||||
|
||||
if (settingsViewModel.clickedItem == null) dismiss()
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
binding = DialogGpuUnswizzleBinding.inflate(LayoutInflater.from(requireContext()))
|
||||
val item = settingsViewModel.clickedItem as GpuUnswizzleSetting
|
||||
|
||||
// Setup texture size dropdown
|
||||
val textureSizeEntries = resources.getStringArray(item.textureSizeChoicesId)
|
||||
val textureSizeValues = resources.getIntArray(item.textureSizeValuesId)
|
||||
val textureSizeAdapter = ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
textureSizeEntries.toMutableList()
|
||||
)
|
||||
binding.dropdownTextureSize.setAdapter(textureSizeAdapter)
|
||||
|
||||
// Setup stream size dropdown
|
||||
val streamSizeEntries = resources.getStringArray(item.streamSizeChoicesId)
|
||||
val streamSizeValues = resources.getIntArray(item.streamSizeValuesId)
|
||||
val streamSizeAdapter = ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
streamSizeEntries.toMutableList()
|
||||
)
|
||||
binding.dropdownStreamSize.setAdapter(streamSizeAdapter)
|
||||
|
||||
// Setup chunk size dropdown
|
||||
val chunkSizeEntries = resources.getStringArray(item.chunkSizeChoicesId)
|
||||
val chunkSizeValues = resources.getIntArray(item.chunkSizeValuesId)
|
||||
val chunkSizeAdapter = ArrayAdapter(
|
||||
requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
chunkSizeEntries.toMutableList()
|
||||
)
|
||||
binding.dropdownChunkSize.setAdapter(chunkSizeAdapter)
|
||||
|
||||
// Load current values
|
||||
val isEnabled = item.isEnabled()
|
||||
binding.switchEnable.isChecked = isEnabled
|
||||
|
||||
if (isEnabled) {
|
||||
val textureSizeIndex = textureSizeValues.indexOf(item.getTextureSize())
|
||||
if (textureSizeIndex >= 0) {
|
||||
binding.dropdownTextureSize.setText(textureSizeEntries[textureSizeIndex], false)
|
||||
}
|
||||
|
||||
val streamSizeIndex = streamSizeValues.indexOf(item.getStreamSize())
|
||||
if (streamSizeIndex >= 0) {
|
||||
binding.dropdownStreamSize.setText(streamSizeEntries[streamSizeIndex], false)
|
||||
}
|
||||
|
||||
val chunkSizeIndex = chunkSizeValues.indexOf(item.getChunkSize())
|
||||
if (chunkSizeIndex >= 0) {
|
||||
binding.dropdownChunkSize.setText(chunkSizeEntries[chunkSizeIndex], false)
|
||||
}
|
||||
} else {
|
||||
// Set default/recommended values when disabling
|
||||
binding.dropdownTextureSize.setText(textureSizeEntries[3], false)
|
||||
binding.dropdownStreamSize.setText(streamSizeEntries[3], false)
|
||||
binding.dropdownChunkSize.setText(chunkSizeEntries[3], false)
|
||||
}
|
||||
|
||||
// Clear adapter filters after setText to fix rotation bug
|
||||
textureSizeAdapter.filter.filter(null)
|
||||
streamSizeAdapter.filter.filter(null)
|
||||
chunkSizeAdapter.filter.filter(null)
|
||||
|
||||
// Enable/disable dropdowns based on switch state
|
||||
updateDropdownsState(isEnabled)
|
||||
binding.switchEnable.setOnCheckedChangeListener { _, checked ->
|
||||
updateDropdownsState(checked)
|
||||
}
|
||||
|
||||
val dialog = MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(item.title)
|
||||
.setView(binding.root)
|
||||
.create()
|
||||
|
||||
// Setup button listeners
|
||||
binding.btnDefault.setOnClickListener {
|
||||
// Reset to defaults
|
||||
item.reset()
|
||||
// Refresh values with adapters reset
|
||||
val textureSizeIndex = textureSizeValues.indexOf(item.getTextureSize())
|
||||
if (textureSizeIndex >= 0) {
|
||||
binding.dropdownTextureSize.setText(textureSizeEntries[textureSizeIndex], false)
|
||||
}
|
||||
val streamSizeIndex = streamSizeValues.indexOf(item.getStreamSize())
|
||||
if (streamSizeIndex >= 0) {
|
||||
binding.dropdownStreamSize.setText(streamSizeEntries[streamSizeIndex], false)
|
||||
}
|
||||
val chunkSizeIndex = chunkSizeValues.indexOf(item.getChunkSize())
|
||||
if (chunkSizeIndex >= 0) {
|
||||
binding.dropdownChunkSize.setText(chunkSizeEntries[chunkSizeIndex], false)
|
||||
}
|
||||
// Clear filters
|
||||
textureSizeAdapter.filter.filter(null)
|
||||
streamSizeAdapter.filter.filter(null)
|
||||
chunkSizeAdapter.filter.filter(null)
|
||||
|
||||
settingsViewModel.setAdapterItemChanged(position)
|
||||
settingsViewModel.setShouldReloadSettingsList(true)
|
||||
}
|
||||
|
||||
binding.btnCancel.setOnClickListener {
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
binding.btnOk.setOnClickListener {
|
||||
if (binding.switchEnable.isChecked) {
|
||||
item.enable()
|
||||
// Save the selected values
|
||||
val selectedTextureIndex = textureSizeEntries.indexOf(
|
||||
binding.dropdownTextureSize.text.toString()
|
||||
)
|
||||
if (selectedTextureIndex >= 0) {
|
||||
item.setTextureSize(textureSizeValues[selectedTextureIndex])
|
||||
}
|
||||
|
||||
val selectedStreamIndex = streamSizeEntries.indexOf(
|
||||
binding.dropdownStreamSize.text.toString()
|
||||
)
|
||||
if (selectedStreamIndex >= 0) {
|
||||
item.setStreamSize(streamSizeValues[selectedStreamIndex])
|
||||
}
|
||||
|
||||
val selectedChunkIndex = chunkSizeEntries.indexOf(
|
||||
binding.dropdownChunkSize.text.toString()
|
||||
)
|
||||
if (selectedChunkIndex >= 0) {
|
||||
item.setChunkSize(chunkSizeValues[selectedChunkIndex])
|
||||
}
|
||||
} else {
|
||||
// Disable GPU unswizzle
|
||||
item.disable()
|
||||
}
|
||||
|
||||
settingsViewModel.setAdapterItemChanged(position)
|
||||
settingsViewModel.setShouldReloadSettingsList(true)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
// Ensure filters are cleared after dialog is shown
|
||||
binding.root.post {
|
||||
textureSizeAdapter.filter.filter(null)
|
||||
streamSizeAdapter.filter.filter(null)
|
||||
chunkSizeAdapter.filter.filter(null)
|
||||
}
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
private fun updateDropdownsState(enabled: Boolean) {
|
||||
binding.layoutTextureSize.isEnabled = enabled
|
||||
binding.dropdownTextureSize.isEnabled = enabled
|
||||
binding.layoutStreamSize.isEnabled = enabled
|
||||
binding.dropdownStreamSize.isEnabled = enabled
|
||||
binding.layoutChunkSize.isEnabled = enabled
|
||||
binding.dropdownChunkSize.isEnabled = enabled
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "GpuUnswizzleDialogFragment"
|
||||
const val POSITION = "Position"
|
||||
|
||||
fun newInstance(
|
||||
settingsViewModel: SettingsViewModel,
|
||||
item: GpuUnswizzleSetting,
|
||||
position: Int
|
||||
): GpuUnswizzleDialogFragment {
|
||||
val dialog = GpuUnswizzleDialogFragment()
|
||||
val args = Bundle()
|
||||
args.putInt(POSITION, position)
|
||||
dialog.arguments = args
|
||||
settingsViewModel.clickedItem = item
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui
|
||||
@@ -101,6 +101,11 @@ class SettingsAdapter(
|
||||
SettingsItem.TYPE_PATH -> {
|
||||
PathViewHolder(ListItemSettingBinding.inflate(inflater), this)
|
||||
}
|
||||
|
||||
SettingsItem.TYPE_GPU_UNSWIZZLE -> {
|
||||
GpuUnswizzleViewHolder(ListItemSettingBinding.inflate(inflater), this)
|
||||
}
|
||||
|
||||
else -> {
|
||||
HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this)
|
||||
}
|
||||
@@ -474,6 +479,14 @@ class SettingsAdapter(
|
||||
settingsViewModel.setShouldShowPathResetDialog(true)
|
||||
}
|
||||
|
||||
fun onGpuUnswizzleClick(item: GpuUnswizzleSetting, position: Int) {
|
||||
GpuUnswizzleDialogFragment.newInstance(
|
||||
settingsViewModel,
|
||||
item,
|
||||
position
|
||||
).show(fragment.childFragmentManager, GpuUnswizzleDialogFragment.TAG)
|
||||
}
|
||||
|
||||
private class DiffCallback : DiffUtil.ItemCallback<SettingsItem>() {
|
||||
override fun areItemsTheSame(oldItem: SettingsItem, newItem: SettingsItem): Boolean {
|
||||
return oldItem.setting.key == newItem.setting.key
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
@@ -68,7 +68,9 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setMessage(R.string.reset_setting_confirmation)
|
||||
.setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int ->
|
||||
when (val item = settingsViewModel.clickedItem) {
|
||||
val item = settingsViewModel.clickedItem ?: return@setPositiveButton
|
||||
clearDialogState()
|
||||
when (item) {
|
||||
is AnalogInputSetting -> {
|
||||
val stickParam = NativeInput.getStickParam(
|
||||
item.playerIndex,
|
||||
@@ -107,12 +109,17 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
|
||||
}
|
||||
|
||||
else -> {
|
||||
settingsViewModel.clickedItem!!.setting.reset()
|
||||
item.setting.reset()
|
||||
settingsViewModel.setAdapterItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setNegativeButton(android.R.string.cancel) { _: DialogInterface, _: Int ->
|
||||
clearDialogState()
|
||||
}
|
||||
.setOnCancelListener {
|
||||
clearDialogState()
|
||||
}
|
||||
.create()
|
||||
}
|
||||
|
||||
@@ -186,27 +193,6 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
|
||||
updateButtonState(isValid)
|
||||
}
|
||||
|
||||
/*
|
||||
* xbzk: these two events, along with attachRepeat feature,
|
||||
* were causing spinbox buttons to respond twice per press
|
||||
* cutting these out to retain accelerated press functionality
|
||||
* TODO: clean this out later if no issues arise
|
||||
*
|
||||
spinboxBinding.buttonDecrement.setOnClickListener {
|
||||
val current = spinboxBinding.editValue.text.toString().toIntOrNull() ?: currentValue
|
||||
val newValue = current - 1
|
||||
spinboxBinding.editValue.setText(newValue.toString())
|
||||
updateValidity(newValue)
|
||||
}
|
||||
|
||||
spinboxBinding.buttonIncrement.setOnClickListener {
|
||||
val current = spinboxBinding.editValue.text.toString().toIntOrNull() ?: currentValue
|
||||
val newValue = current + 1
|
||||
spinboxBinding.editValue.setText(newValue.toString())
|
||||
updateValidity(newValue)
|
||||
}
|
||||
*/
|
||||
|
||||
fun attachRepeat(button: View, delta: Int) {
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
var runnable: Runnable? = null
|
||||
@@ -439,9 +425,13 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
|
||||
|
||||
private fun closeDialog() {
|
||||
settingsViewModel.setAdapterItemChanged(position)
|
||||
clearDialogState()
|
||||
dismiss()
|
||||
}
|
||||
|
||||
private fun clearDialogState() {
|
||||
settingsViewModel.clickedItem = null
|
||||
settingsViewModel.setSliderProgress(-1f)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
private fun getValueForSingleChoiceSelection(item: SingleChoiceSetting, which: Int): Int {
|
||||
|
||||
@@ -227,6 +227,8 @@ class SettingsFragmentPresenter(
|
||||
add(StringSetting.DEVICE_NAME.key)
|
||||
add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key)
|
||||
add(ShortSetting.RENDERER_SPEED_LIMIT.key)
|
||||
add(ShortSetting.RENDERER_TURBO_SPEED_LIMIT.key)
|
||||
add(ShortSetting.RENDERER_SLOW_SPEED_LIMIT.key)
|
||||
add(BooleanSetting.USE_DOCKED_MODE.key)
|
||||
add(IntSetting.REGION_INDEX.key)
|
||||
add(IntSetting.LANGUAGE_INDEX.key)
|
||||
@@ -235,7 +237,6 @@ class SettingsFragmentPresenter(
|
||||
|
||||
add(HeaderSetting(R.string.cpu))
|
||||
add(IntSetting.FAST_CPU_TIME.key)
|
||||
add(BooleanSetting.USE_LRU_CACHE.key)
|
||||
add(BooleanSetting.CORE_SYNC_CORE_SPEED.key)
|
||||
|
||||
add(IntSetting.MEMORY_LAYOUT.key)
|
||||
@@ -269,12 +270,13 @@ class SettingsFragmentPresenter(
|
||||
add(IntSetting.MAX_ANISOTROPY.key)
|
||||
add(IntSetting.RENDERER_VRAM_USAGE_MODE.key)
|
||||
add(IntSetting.RENDERER_ASTC_DECODE_METHOD.key)
|
||||
add(IntSetting.RENDERER_ASTC_RECOMPRESSION.key)
|
||||
|
||||
add(BooleanSetting.SYNC_MEMORY_OPERATIONS.key)
|
||||
add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key)
|
||||
add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
|
||||
add(BooleanSetting.RENDERER_REACTIVE_FLUSHING.key)
|
||||
add(BooleanSetting.ENABLE_BUFFER_HISTORY.key)
|
||||
add(BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS.key)
|
||||
|
||||
add(HeaderSetting(R.string.hacks))
|
||||
|
||||
@@ -282,14 +284,12 @@ class SettingsFragmentPresenter(
|
||||
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
|
||||
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
|
||||
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
|
||||
add(IntSetting.GPU_UNSWIZZLE_TEXTURE_SIZE.key)
|
||||
add(IntSetting.GPU_UNSWIZZLE_STREAM_SIZE.key)
|
||||
add(IntSetting.GPU_UNSWIZZLE_CHUNK_SIZE.key)
|
||||
add(SettingsItem.GPU_UNSWIZZLE_COMBINED)
|
||||
|
||||
add(HeaderSetting(R.string.extensions))
|
||||
|
||||
add(IntSetting.RENDERER_DYNA_STATE.key)
|
||||
add(BooleanSetting.RENDERER_VERTEX_INPUT_DYNAMIC_STATE.key)
|
||||
add(BooleanSetting.RENDERER_DESCRIPTOR_INDEXING.key)
|
||||
add(IntSetting.RENDERER_SAMPLE_SHADING.key)
|
||||
|
||||
add(HeaderSetting(R.string.display))
|
||||
@@ -1062,7 +1062,10 @@ class SettingsFragmentPresenter(
|
||||
IntSetting.THEME.getValueAsString()
|
||||
|
||||
override val defaultValue: Int = IntSetting.THEME.defaultValue
|
||||
override fun reset() = IntSetting.THEME.setInt(defaultValue)
|
||||
override fun reset() {
|
||||
IntSetting.THEME.setInt(defaultValue)
|
||||
settingsViewModel.setShouldRecreate(true)
|
||||
}
|
||||
}
|
||||
|
||||
add(HeaderSetting(R.string.app_settings))
|
||||
@@ -1072,6 +1075,9 @@ class SettingsFragmentPresenter(
|
||||
add(BooleanSetting.ENABLE_UPDATE_CHECKS.key)
|
||||
}
|
||||
|
||||
add(BooleanSetting.ENABLE_QUICK_SETTINGS.key)
|
||||
add(BooleanSetting.INVERT_CONFIRM_BACK_CONTROLLER_BUTTONS.key)
|
||||
|
||||
add(HeaderSetting(R.string.theme_and_color))
|
||||
|
||||
|
||||
@@ -1117,23 +1123,24 @@ class SettingsFragmentPresenter(
|
||||
}
|
||||
|
||||
val staticThemeColor: AbstractIntSetting = object : AbstractIntSetting {
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(
|
||||
YuzuApplication.appContext
|
||||
)
|
||||
override fun getInt(needsGlobal: Boolean): Int =
|
||||
preferences.getInt(Settings.PREF_STATIC_THEME_COLOR, 0)
|
||||
IntSetting.STATIC_THEME_COLOR.getInt(needsGlobal)
|
||||
|
||||
override fun setInt(value: Int) {
|
||||
preferences.edit() { putInt(Settings.PREF_STATIC_THEME_COLOR, value) }
|
||||
IntSetting.STATIC_THEME_COLOR.setInt(value)
|
||||
settingsViewModel.setShouldRecreate(true)
|
||||
}
|
||||
|
||||
override val key: String = Settings.PREF_STATIC_THEME_COLOR
|
||||
override val key: String = IntSetting.STATIC_THEME_COLOR.key
|
||||
override val isRuntimeModifiable: Boolean = true
|
||||
|
||||
override fun getValueAsString(needsGlobal: Boolean): String =
|
||||
preferences.getInt(Settings.PREF_STATIC_THEME_COLOR, 0).toString()
|
||||
override val defaultValue: Any = 0
|
||||
IntSetting.STATIC_THEME_COLOR.getValueAsString(needsGlobal)
|
||||
|
||||
override val defaultValue: Any = IntSetting.STATIC_THEME_COLOR.defaultValue
|
||||
|
||||
override fun reset() {
|
||||
preferences.edit() { putInt(Settings.PREF_STATIC_THEME_COLOR, 0) }
|
||||
IntSetting.STATIC_THEME_COLOR.reset()
|
||||
settingsViewModel.setShouldRecreate(true)
|
||||
}
|
||||
}
|
||||
@@ -1189,6 +1196,13 @@ class SettingsFragmentPresenter(
|
||||
descriptionId = R.string.use_black_backgrounds_description
|
||||
)
|
||||
)
|
||||
|
||||
add(HeaderSetting(R.string.buttons))
|
||||
add(BooleanSetting.ENABLE_FOLDER_BUTTON.key)
|
||||
add(BooleanSetting.ENABLE_QLAUNCH_BUTTON.key)
|
||||
if (!NativeLibrary.isFirmwareAvailable()) {
|
||||
BooleanSetting.ENABLE_QLAUNCH_BUTTON.setBoolean(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1217,7 +1231,7 @@ class SettingsFragmentPresenter(
|
||||
|
||||
add(HeaderSetting(R.string.general))
|
||||
|
||||
add(IntSetting.DEBUG_KNOBS.key)
|
||||
add(ShortSetting.DEBUG_KNOBS.key)
|
||||
|
||||
add(HeaderSetting(R.string.gpu_logging_header))
|
||||
add(BooleanSetting.GPU_LOGGING_ENABLED.key)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
||||
|
||||
import android.view.View
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.GpuUnswizzleSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
||||
|
||||
class GpuUnswizzleViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
|
||||
SettingViewHolder(binding.root, adapter) {
|
||||
private lateinit var setting: GpuUnswizzleSetting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
setting = item as GpuUnswizzleSetting
|
||||
binding.textSettingName.text = setting.title
|
||||
binding.textSettingDescription.setVisible(item.description.isNotEmpty())
|
||||
binding.textSettingDescription.text = item.description
|
||||
|
||||
binding.textSettingValue.setVisible(true)
|
||||
val resMgr = binding.root.context.resources
|
||||
|
||||
if (setting.isEnabled()) {
|
||||
// Show a summary of current settings
|
||||
val textureSizeEntries = resMgr.getStringArray(setting.textureSizeChoicesId)
|
||||
val textureSizeValues = resMgr.getIntArray(setting.textureSizeValuesId)
|
||||
val textureSizeIndex = textureSizeValues.indexOf(setting.getTextureSize())
|
||||
val textureSizeLabel = if (textureSizeIndex >= 0) textureSizeEntries[textureSizeIndex] else "?"
|
||||
|
||||
val streamSizeEntries = resMgr.getStringArray(setting.streamSizeChoicesId)
|
||||
val streamSizeValues = resMgr.getIntArray(setting.streamSizeValuesId)
|
||||
val streamSizeIndex = streamSizeValues.indexOf(setting.getStreamSize())
|
||||
val streamSizeLabel = if (streamSizeIndex >= 0) streamSizeEntries[streamSizeIndex] else "?"
|
||||
|
||||
val chunkSizeEntries = resMgr.getStringArray(setting.chunkSizeChoicesId)
|
||||
val chunkSizeValues = resMgr.getIntArray(setting.chunkSizeValuesId)
|
||||
val chunkSizeIndex = chunkSizeValues.indexOf(setting.getChunkSize())
|
||||
val chunkSizeLabel = if (chunkSizeIndex >= 0) chunkSizeEntries[chunkSizeIndex] else "?"
|
||||
|
||||
binding.textSettingValue.text = "$textureSizeLabel ⋅ $streamSizeLabel ⋅ $chunkSizeLabel"
|
||||
} else {
|
||||
binding.textSettingValue.text = resMgr.getString(R.string.gpu_unswizzle_disabled)
|
||||
}
|
||||
|
||||
binding.buttonClear.setVisible(setting.clearable)
|
||||
binding.buttonClear.setOnClickListener {
|
||||
adapter.onClearClick(setting, bindingAdapterPosition)
|
||||
}
|
||||
|
||||
setStyle(setting.isEditable, binding)
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (!setting.isEditable) {
|
||||
return
|
||||
}
|
||||
|
||||
adapter.onGpuUnswizzleClick(setting, bindingAdapterPosition)
|
||||
}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean {
|
||||
if (setting.isEditable) {
|
||||
return adapter.onLongClick(setting, bindingAdapterPosition)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,459 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.fragments
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.ImageDecoder
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.adapters.FirmwareAvatarAdapter
|
||||
import org.yuzu.yuzu_emu.databinding.FragmentEditUserDialogBinding
|
||||
import org.yuzu.yuzu_emu.model.HomeViewModel
|
||||
import org.yuzu.yuzu_emu.model.ProfileUtils
|
||||
import org.yuzu.yuzu_emu.model.UserProfile
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import androidx.core.graphics.scale
|
||||
import androidx.core.graphics.createBitmap
|
||||
|
||||
class EditUserDialogFragment : Fragment() {
|
||||
private var _binding: FragmentEditUserDialogBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val homeViewModel: HomeViewModel by activityViewModels()
|
||||
|
||||
private var currentUUID: String = ""
|
||||
private var isEditMode = false
|
||||
private var selectedImageUri: Uri? = null
|
||||
private var selectedFirmwareAvatar: Bitmap? = null
|
||||
private var hasCustomImage = false
|
||||
private var revertedToDefault = false
|
||||
|
||||
companion object {
|
||||
private const val ARG_UUID = "uuid"
|
||||
private const val ARG_USERNAME = "username"
|
||||
|
||||
fun newInstance(profile: UserProfile?): EditUserDialogFragment {
|
||||
val fragment = EditUserDialogFragment()
|
||||
profile?.let {
|
||||
val args = Bundle()
|
||||
args.putString(ARG_UUID, it.uuid)
|
||||
args.putString(ARG_USERNAME, it.username)
|
||||
fragment.arguments = args
|
||||
}
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
private val imagePickerLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
result.data?.data?.let { uri ->
|
||||
selectedImageUri = uri
|
||||
loadImage(uri)
|
||||
hasCustomImage = true
|
||||
binding.buttonRevertImage.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentEditUserDialogBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
homeViewModel.setStatusBarShadeVisibility(visible = false)
|
||||
|
||||
val existingUUID = arguments?.getString(ARG_UUID)
|
||||
val existingUsername = arguments?.getString(ARG_USERNAME)
|
||||
|
||||
if (existingUUID != null && existingUsername != null) {
|
||||
isEditMode = true
|
||||
currentUUID = existingUUID
|
||||
binding.toolbarNewUser.title = getString(R.string.profile_edit_user)
|
||||
binding.editUsername.setText(existingUsername)
|
||||
binding.textUuid.text = formatUUID(existingUUID)
|
||||
binding.buttonGenerateUuid.visibility = View.GONE
|
||||
|
||||
val imagePath = NativeLibrary.getUserImagePath(existingUUID)
|
||||
val imageFile = File(imagePath)
|
||||
if (imageFile.exists()) {
|
||||
val bitmap = BitmapFactory.decodeFile(imagePath)
|
||||
binding.imageUserAvatar.setImageBitmap(bitmap)
|
||||
hasCustomImage = true
|
||||
binding.buttonRevertImage.visibility = View.VISIBLE
|
||||
} else {
|
||||
loadDefaultAvatar()
|
||||
}
|
||||
} else {
|
||||
isEditMode = false
|
||||
currentUUID = ProfileUtils.generateRandomUUID()
|
||||
binding.toolbarNewUser.title = getString(R.string.profile_new_user)
|
||||
binding.textUuid.text = formatUUID(currentUUID)
|
||||
loadDefaultAvatar()
|
||||
}
|
||||
|
||||
binding.toolbarNewUser.setNavigationOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
|
||||
binding.editUsername.doAfterTextChanged {
|
||||
validateInput()
|
||||
}
|
||||
|
||||
binding.buttonGenerateUuid.setOnClickListener {
|
||||
currentUUID = ProfileUtils.generateRandomUUID()
|
||||
binding.textUuid.text = formatUUID(currentUUID)
|
||||
}
|
||||
|
||||
binding.buttonSelectImage.setOnClickListener {
|
||||
selectImage()
|
||||
}
|
||||
|
||||
binding.buttonRevertImage.setOnClickListener {
|
||||
revertToDefaultImage()
|
||||
}
|
||||
|
||||
if (NativeLibrary.isFirmwareAvailable()) {
|
||||
binding.buttonFirmwareAvatars.visibility = View.VISIBLE
|
||||
binding.buttonFirmwareAvatars.setOnClickListener {
|
||||
showFirmwareAvatarPicker()
|
||||
}
|
||||
}
|
||||
|
||||
binding.buttonSave.setOnClickListener {
|
||||
saveUser()
|
||||
}
|
||||
|
||||
binding.buttonCancel.setOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
|
||||
validateInput()
|
||||
setInsets()
|
||||
}
|
||||
|
||||
private fun showFirmwareAvatarPicker() {
|
||||
val dialogView = LayoutInflater.from(requireContext())
|
||||
.inflate(R.layout.dialog_firmware_avatar_picker, null)
|
||||
|
||||
val gridAvatars = dialogView.findViewById<RecyclerView>(R.id.grid_avatars)
|
||||
val progressLoading = dialogView.findViewById<View>(R.id.progress_loading)
|
||||
val textEmpty = dialogView.findViewById<View>(R.id.text_empty)
|
||||
|
||||
val dialog = MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.profile_firmware_avatars)
|
||||
.setView(dialogView)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create()
|
||||
|
||||
dialog.show()
|
||||
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val avatars = withContext(Dispatchers.IO) {
|
||||
loadFirmwareAvatars()
|
||||
}
|
||||
|
||||
if (avatars.isEmpty()) {
|
||||
progressLoading.visibility = View.GONE
|
||||
textEmpty.visibility = View.VISIBLE
|
||||
} else {
|
||||
progressLoading.visibility = View.GONE
|
||||
gridAvatars.visibility = View.VISIBLE
|
||||
|
||||
val adapter = FirmwareAvatarAdapter(avatars) { selectedAvatar ->
|
||||
val scaledBitmap = selectedAvatar.scale(256, 256)
|
||||
binding.imageUserAvatar.setImageBitmap(scaledBitmap)
|
||||
selectedFirmwareAvatar = scaledBitmap
|
||||
hasCustomImage = true
|
||||
binding.buttonRevertImage.visibility = View.VISIBLE
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
gridAvatars.apply {
|
||||
layoutManager = GridLayoutManager(requireContext(), 4)
|
||||
this.adapter = adapter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadFirmwareAvatars(): List<Bitmap> {
|
||||
val avatars = mutableListOf<Bitmap>()
|
||||
val count = NativeLibrary.getFirmwareAvatarCount()
|
||||
|
||||
for (i in 0 until count) {
|
||||
try {
|
||||
val imageData = NativeLibrary.getFirmwareAvatarImage(i) ?: continue
|
||||
|
||||
val argbData = IntArray(256 * 256)
|
||||
for (pixel in 0 until 256 * 256) {
|
||||
val offset = pixel * 4
|
||||
val r = imageData[offset].toInt() and 0xFF
|
||||
val g = imageData[offset + 1].toInt() and 0xFF
|
||||
val b = imageData[offset + 2].toInt() and 0xFF
|
||||
val a = imageData[offset + 3].toInt() and 0xFF
|
||||
argbData[pixel] = (a shl 24) or (r shl 16) or (g shl 8) or b
|
||||
}
|
||||
|
||||
val bitmap = Bitmap.createBitmap(argbData, 256, 256, Bitmap.Config.ARGB_8888)
|
||||
avatars.add(bitmap)
|
||||
} catch (e: Exception) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return avatars
|
||||
}
|
||||
|
||||
private fun formatUUID(uuid: String): String {
|
||||
if (uuid.length != 32) return uuid
|
||||
return buildString {
|
||||
append(uuid.substring(0, 8))
|
||||
append("-")
|
||||
append(uuid.substring(8, 12))
|
||||
append("-")
|
||||
append(uuid.substring(12, 16))
|
||||
append("-")
|
||||
append(uuid.substring(16, 20))
|
||||
append("-")
|
||||
append(uuid.substring(20, 32))
|
||||
}
|
||||
}
|
||||
|
||||
private fun validateInput() {
|
||||
val username = binding.editUsername.text.toString()
|
||||
val isValid = username.isNotEmpty() && username.length <= 32
|
||||
binding.buttonSave.isEnabled = isValid
|
||||
}
|
||||
|
||||
private fun selectImage() {
|
||||
val intent = Intent(Intent.ACTION_PICK).apply {
|
||||
type = "image/*"
|
||||
}
|
||||
imagePickerLauncher.launch(intent)
|
||||
}
|
||||
|
||||
private fun loadImage(uri: Uri) {
|
||||
try {
|
||||
val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
val source = ImageDecoder.createSource(requireContext().contentResolver, uri)
|
||||
ImageDecoder.decodeBitmap(source) { decoder, _, _ ->
|
||||
decoder.setTargetSampleSize(1)
|
||||
}
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
MediaStore.Images.Media.getBitmap(requireContext().contentResolver, uri)
|
||||
}
|
||||
|
||||
val croppedBitmap = centerCropBitmap(bitmap, 256, 256)
|
||||
binding.imageUserAvatar.setImageBitmap(croppedBitmap)
|
||||
} catch (e: Exception) {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.error)
|
||||
.setMessage(getString(R.string.profile_image_load_error, e.message))
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadDefaultAvatar() {
|
||||
val jpegData = NativeLibrary.getDefaultAccountBackupJpeg()
|
||||
val bitmap = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.size)
|
||||
binding.imageUserAvatar.setImageBitmap(bitmap)
|
||||
|
||||
hasCustomImage = false
|
||||
binding.buttonRevertImage.visibility = View.GONE
|
||||
}
|
||||
|
||||
private fun revertToDefaultImage() {
|
||||
selectedImageUri = null
|
||||
selectedFirmwareAvatar = null
|
||||
revertedToDefault = true
|
||||
loadDefaultAvatar()
|
||||
}
|
||||
|
||||
private fun saveUser() {
|
||||
val username = binding.editUsername.text.toString()
|
||||
|
||||
if (isEditMode) {
|
||||
if (NativeLibrary.updateUserUsername(currentUUID, username)) {
|
||||
saveImageIfNeeded()
|
||||
findNavController().popBackStack()
|
||||
} else {
|
||||
showError(getString(R.string.profile_update_failed))
|
||||
}
|
||||
} else {
|
||||
if (NativeLibrary.createUser(currentUUID, username)) {
|
||||
saveImageIfNeeded()
|
||||
findNavController().popBackStack()
|
||||
} else {
|
||||
showError(getString(R.string.profile_create_failed))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveImageIfNeeded() {
|
||||
if (revertedToDefault && isEditMode) {
|
||||
val imagePath = NativeLibrary.getUserImagePath(currentUUID)
|
||||
if (imagePath != null) {
|
||||
val imageFile = File(imagePath)
|
||||
if (imageFile.exists()) {
|
||||
imageFile.delete()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (!hasCustomImage) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
val bitmapToSave: Bitmap? = when {
|
||||
selectedFirmwareAvatar != null -> selectedFirmwareAvatar
|
||||
selectedImageUri != null -> {
|
||||
val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
val source = ImageDecoder.createSource(
|
||||
requireContext().contentResolver,
|
||||
selectedImageUri!!
|
||||
)
|
||||
ImageDecoder.decodeBitmap(source)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
MediaStore.Images.Media.getBitmap(
|
||||
requireContext().contentResolver,
|
||||
selectedImageUri
|
||||
)
|
||||
}
|
||||
centerCropBitmap(bitmap, 256, 256)
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (bitmapToSave == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val tempFile = File(requireContext().cacheDir, "temp_avatar_${currentUUID}.jpg")
|
||||
FileOutputStream(tempFile).use { out ->
|
||||
bitmapToSave.compress(Bitmap.CompressFormat.JPEG, 100, out)
|
||||
}
|
||||
|
||||
NativeLibrary.saveUserImage(currentUUID, tempFile.absolutePath)
|
||||
|
||||
tempFile.delete()
|
||||
} catch (e: Exception) {
|
||||
showError(getString(R.string.profile_image_save_error, e.message))
|
||||
}
|
||||
}
|
||||
|
||||
private fun centerCropBitmap(source: Bitmap, targetWidth: Int, targetHeight: Int): Bitmap {
|
||||
val sourceWidth = source.width
|
||||
val sourceHeight = source.height
|
||||
|
||||
val scale = maxOf(
|
||||
targetWidth.toFloat() / sourceWidth,
|
||||
targetHeight.toFloat() / sourceHeight
|
||||
)
|
||||
|
||||
val scaledWidth = (sourceWidth * scale).toInt()
|
||||
val scaledHeight = (sourceHeight * scale).toInt()
|
||||
|
||||
val scaledBitmap = source.scale(scaledWidth, scaledHeight)
|
||||
|
||||
val x = (scaledWidth - targetWidth) / 2
|
||||
val y = (scaledHeight - targetHeight) / 2
|
||||
|
||||
return Bitmap.createBitmap(scaledBitmap, x, y, targetWidth, targetHeight)
|
||||
}
|
||||
|
||||
private fun showError(message: String) {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.error)
|
||||
.setMessage(message)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
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 leftInset = barInsets.left + cutoutInsets.left
|
||||
val topInset = cutoutInsets.top
|
||||
val rightInset = barInsets.right + cutoutInsets.right
|
||||
val bottomInset = barInsets.bottom + cutoutInsets.bottom
|
||||
|
||||
binding.appbar.updatePadding(
|
||||
left = leftInset,
|
||||
top = topInset,
|
||||
right = rightInset
|
||||
)
|
||||
|
||||
binding.scrollContent.updatePadding(
|
||||
left = leftInset,
|
||||
right = rightInset
|
||||
)
|
||||
|
||||
binding.buttonContainer.updatePadding(
|
||||
left = leftInset,
|
||||
right = rightInset,
|
||||
bottom = bottomInset
|
||||
)
|
||||
|
||||
windowInsets
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.BatteryManager
|
||||
import android.os.BatteryManager.*
|
||||
@@ -55,6 +56,7 @@ import androidx.window.layout.WindowInfoTracker
|
||||
import androidx.window.layout.WindowLayoutInfo
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.materialswitch.MaterialSwitch
|
||||
import com.google.android.material.textview.MaterialTextView
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -96,6 +98,7 @@ import org.yuzu.yuzu_emu.utils.collect
|
||||
import org.yuzu.yuzu_emu.utils.CustomSettingsHandler
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.nio.ByteBuffer
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlin.or
|
||||
@@ -140,6 +143,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
|
||||
private var wasInputOverlayAutoHidden = false
|
||||
private var overlayTouchActive = false
|
||||
private var pausedFrameBitmap: Bitmap? = null
|
||||
|
||||
var shouldUseCustom = false
|
||||
private var isQuickSettingsMenuOpen = false
|
||||
@@ -690,8 +694,24 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
})
|
||||
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||
|
||||
if (!BooleanSetting.ENABLE_QUICK_SETTINGS.getBoolean()) {
|
||||
binding.drawerLayout.setDrawerLockMode(
|
||||
DrawerLayout.LOCK_MODE_LOCKED_CLOSED,
|
||||
binding.quickSettingsSheet
|
||||
)
|
||||
}
|
||||
|
||||
updateGameTitle()
|
||||
|
||||
binding.inGameMenu.menu.findItem(R.id.menu_quick_settings)?.isVisible =
|
||||
BooleanSetting.ENABLE_QUICK_SETTINGS.getBoolean()
|
||||
|
||||
binding.pausedIcon.setOnClickListener {
|
||||
if (this::emulationState.isInitialized && emulationState.isPaused) {
|
||||
resumeEmulationFromUi()
|
||||
}
|
||||
}
|
||||
|
||||
binding.inGameMenu.menu.findItem(R.id.menu_lock_drawer).apply {
|
||||
val lockMode = IntSetting.LOCK_DRAWER.getInt()
|
||||
val titleId = if (lockMode == DrawerLayout.LOCK_MODE_LOCKED_CLOSED) {
|
||||
@@ -717,11 +737,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
when (it.itemId) {
|
||||
R.id.menu_pause_emulation -> {
|
||||
if (emulationState.isPaused) {
|
||||
emulationState.run(false)
|
||||
updatePauseMenuEntry(false)
|
||||
resumeEmulationFromUi()
|
||||
} else {
|
||||
emulationState.pause()
|
||||
updatePauseMenuEntry(true)
|
||||
pauseEmulationAndCaptureFrame()
|
||||
}
|
||||
binding.inGameMenu.requestFocus()
|
||||
true
|
||||
@@ -749,10 +767,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_quick_settings -> {
|
||||
openQuickSettingsMenu()
|
||||
true
|
||||
}
|
||||
if (BooleanSetting.ENABLE_QUICK_SETTINGS.getBoolean())
|
||||
R.id.menu_quick_settings else 0 -> {
|
||||
openQuickSettingsMenu()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_settings_per_game -> {
|
||||
val action = HomeNavigationDirections.actionGlobalSettingsActivity(
|
||||
@@ -814,6 +833,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
}
|
||||
|
||||
R.id.menu_exit -> {
|
||||
clearPausedFrame()
|
||||
emulationState.stop()
|
||||
NativeConfig.reloadGlobalConfig()
|
||||
emulationViewModel.setIsEmulationStopping(true)
|
||||
@@ -1044,12 +1064,50 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
quickSettings.addPerGameConfigStatusIndicator(container)
|
||||
}
|
||||
|
||||
quickSettings.addBooleanSetting(
|
||||
container,
|
||||
BooleanSetting.RENDERER_USE_SPEED_LIMIT,
|
||||
)
|
||||
lateinit var slowSpeed: MaterialSwitch
|
||||
lateinit var turboSpeed: MaterialSwitch
|
||||
|
||||
turboSpeed = quickSettings.addCustomToggle(
|
||||
R.string.turbo_speed_limit,
|
||||
NativeLibrary.isTurboMode(),
|
||||
BooleanSetting.RENDERER_USE_SPEED_LIMIT.getBoolean(false),
|
||||
container
|
||||
) { enabled ->
|
||||
if (enabled)
|
||||
slowSpeed.isChecked = false
|
||||
NativeLibrary.setTurboSpeedLimit(enabled)
|
||||
}!!
|
||||
|
||||
slowSpeed = quickSettings.addCustomToggle(
|
||||
R.string.slow_speed_limit,
|
||||
NativeLibrary.isSlowMode(),
|
||||
BooleanSetting.RENDERER_USE_SPEED_LIMIT.getBoolean(false),
|
||||
container
|
||||
) { enabled ->
|
||||
if (enabled)
|
||||
turboSpeed.isChecked = false
|
||||
NativeLibrary.setSlowSpeedLimit(enabled)
|
||||
}!!
|
||||
|
||||
quickSettings.addCustomToggle(
|
||||
R.string.frame_limit_enable,
|
||||
BooleanSetting.RENDERER_USE_SPEED_LIMIT.getBoolean(false),
|
||||
true,
|
||||
container
|
||||
) { enabled ->
|
||||
if (!enabled) {
|
||||
turboSpeed.isChecked = false
|
||||
slowSpeed.isChecked = false
|
||||
}
|
||||
|
||||
turboSpeed.isEnabled = enabled
|
||||
slowSpeed.isEnabled = enabled
|
||||
|
||||
NativeLibrary.setStandardSpeedLimit(enabled)
|
||||
}!!
|
||||
|
||||
quickSettings.addSliderSetting(
|
||||
R.string.frame_limit_slider,
|
||||
container,
|
||||
ShortSetting.RENDERER_SPEED_LIMIT,
|
||||
minValue = 0,
|
||||
@@ -1058,6 +1116,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
)
|
||||
|
||||
quickSettings.addBooleanSetting(
|
||||
R.string.use_docked_mode,
|
||||
container,
|
||||
BooleanSetting.USE_DOCKED_MODE,
|
||||
)
|
||||
@@ -1065,6 +1124,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
quickSettings.addDivider(container)
|
||||
|
||||
quickSettings.addIntSetting(
|
||||
R.string.renderer_accuracy,
|
||||
container,
|
||||
IntSetting.RENDERER_ACCURACY,
|
||||
R.array.rendererAccuracyNames,
|
||||
@@ -1073,6 +1133,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
|
||||
|
||||
quickSettings.addIntSetting(
|
||||
R.string.renderer_scaling_filter,
|
||||
container,
|
||||
IntSetting.RENDERER_SCALING_FILTER,
|
||||
R.array.rendererScalingFilterNames,
|
||||
@@ -1080,6 +1141,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
)
|
||||
|
||||
quickSettings.addSliderSetting(
|
||||
R.string.fsr_sharpness,
|
||||
container,
|
||||
IntSetting.FSR_SHARPENING_SLIDER,
|
||||
minValue = 0,
|
||||
@@ -1088,6 +1150,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
)
|
||||
|
||||
quickSettings.addIntSetting(
|
||||
R.string.renderer_anti_aliasing,
|
||||
container,
|
||||
IntSetting.RENDERER_ANTI_ALIASING,
|
||||
R.array.rendererAntiAliasingNames,
|
||||
@@ -1142,6 +1205,71 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
private fun pauseEmulationAndCaptureFrame() {
|
||||
emulationState.pause()
|
||||
updatePauseMenuEntry(true)
|
||||
capturePausedFrameFromCore()
|
||||
updatePausedFrameVisibility()
|
||||
}
|
||||
|
||||
private fun capturePausedFrameFromCore() {
|
||||
lifecycleScope.launch(Dispatchers.Default) {
|
||||
val frameData = NativeLibrary.getAppletCaptureBuffer()
|
||||
val width = NativeLibrary.getAppletCaptureWidth()
|
||||
val height = NativeLibrary.getAppletCaptureHeight()
|
||||
if (frameData.isEmpty() || width <= 0 || height <= 0) {
|
||||
Log.warning(
|
||||
"[EmulationFragment] Paused frame capture returned empty/invalid data. " +
|
||||
"size=${frameData.size}, width=$width, height=$height"
|
||||
)
|
||||
return@launch
|
||||
}
|
||||
|
||||
val expectedSize = width * height * 4
|
||||
if (frameData.size < expectedSize) {
|
||||
Log.warning(
|
||||
"[EmulationFragment] Paused frame buffer smaller than expected. " +
|
||||
"size=${frameData.size}, expected=$expectedSize"
|
||||
)
|
||||
return@launch
|
||||
}
|
||||
|
||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
bitmap.copyPixelsFromBuffer(ByteBuffer.wrap(frameData, 0, expectedSize))
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
pausedFrameBitmap?.recycle()
|
||||
pausedFrameBitmap = bitmap
|
||||
updatePausedFrameVisibility()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePausedFrameVisibility() {
|
||||
val b = _binding ?: return
|
||||
val showPausedUi = this::emulationState.isInitialized && emulationState.isPaused
|
||||
b.pausedIcon.setVisible(showPausedUi)
|
||||
|
||||
val bitmap = if (showPausedUi) pausedFrameBitmap else null
|
||||
b.pausedFrameImage.setImageBitmap(bitmap)
|
||||
b.pausedFrameImage.setVisible(bitmap != null)
|
||||
}
|
||||
|
||||
private fun resumeEmulationFromUi() {
|
||||
clearPausedFrame()
|
||||
emulationState.resume()
|
||||
updatePauseMenuEntry(emulationState.isPaused)
|
||||
updatePausedFrameVisibility()
|
||||
}
|
||||
|
||||
private fun clearPausedFrame() {
|
||||
val b = _binding
|
||||
b?.pausedFrameImage?.setVisible(false)
|
||||
b?.pausedFrameImage?.setImageDrawable(null)
|
||||
pausedFrameBitmap?.recycle()
|
||||
pausedFrameBitmap = null
|
||||
}
|
||||
|
||||
private fun handleLoadAmiiboSelection(): Boolean {
|
||||
val binding = _binding ?: return true
|
||||
|
||||
@@ -1235,8 +1363,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
override fun onPause() {
|
||||
if (this::emulationState.isInitialized) {
|
||||
if (emulationState.isRunning && emulationActivity?.isInPictureInPictureMode != true) {
|
||||
emulationState.pause()
|
||||
updatePauseMenuEntry(true)
|
||||
pauseEmulationAndCaptureFrame()
|
||||
} else {
|
||||
updatePausedFrameVisibility()
|
||||
}
|
||||
}
|
||||
super.onPause()
|
||||
@@ -1246,6 +1375,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
super.onDestroyView()
|
||||
amiiboLoadJob?.cancel()
|
||||
amiiboLoadJob = null
|
||||
clearPausedFrame()
|
||||
_binding?.surfaceInputOverlay?.touchEventListener = null
|
||||
_binding = null
|
||||
isAmiiboPickerOpen = false
|
||||
@@ -1266,6 +1396,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
b.inGameMenu.post {
|
||||
if (!this::emulationState.isInitialized || _binding == null) return@post
|
||||
updatePauseMenuEntry(emulationState.isPaused)
|
||||
updatePausedFrameVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1705,6 +1836,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
// Only update surface reference, don't trigger state changes
|
||||
emulationState.updateSurfaceReference(holder.surface)
|
||||
}
|
||||
updatePausedFrameVisibility()
|
||||
}
|
||||
|
||||
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
||||
@@ -2035,6 +2167,29 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun resume() {
|
||||
if (state != State.PAUSED) {
|
||||
Log.warning("[EmulationFragment] Resume called while emulation is not paused.")
|
||||
return
|
||||
}
|
||||
if (!emulationCanStart.invoke()) {
|
||||
Log.warning("[EmulationFragment] Resume blocked by emulationCanStart check.")
|
||||
return
|
||||
}
|
||||
val currentSurface = surface
|
||||
if (currentSurface == null || !currentSurface.isValid) {
|
||||
Log.debug("[EmulationFragment] Resume requested with invalid surface.")
|
||||
return
|
||||
}
|
||||
|
||||
NativeLibrary.surfaceChanged(currentSurface)
|
||||
Log.debug("[EmulationFragment] Resuming emulation.")
|
||||
NativeLibrary.unpauseEmulation()
|
||||
NativeLibrary.playTimeManagerStart()
|
||||
state = State.RUNNING
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun changeProgram(programIndex: Int) {
|
||||
emulationThread.join()
|
||||
@@ -2056,7 +2211,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
|
||||
@Synchronized
|
||||
fun updateSurface() {
|
||||
if (surface != null) {
|
||||
if (surface != null && state == State.RUNNING) {
|
||||
NativeLibrary.surfaceChanged(surface)
|
||||
}
|
||||
}
|
||||
@@ -2072,20 +2227,20 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
@Synchronized
|
||||
fun clearSurface() {
|
||||
if (surface == null) {
|
||||
Log.warning("[EmulationFragment] clearSurface called, but surface already null.")
|
||||
Log.debug("[EmulationFragment] clearSurface called, but surface already null.")
|
||||
} else {
|
||||
if (state == State.RUNNING) {
|
||||
pause()
|
||||
}
|
||||
NativeLibrary.surfaceDestroyed()
|
||||
surface = null
|
||||
Log.debug("[EmulationFragment] Surface destroyed.")
|
||||
when (state) {
|
||||
State.RUNNING -> {
|
||||
state = State.PAUSED
|
||||
}
|
||||
|
||||
State.PAUSED -> Log.warning(
|
||||
State.PAUSED -> Log.debug(
|
||||
"[EmulationFragment] Surface cleared while emulation paused."
|
||||
)
|
||||
|
||||
else -> Log.warning(
|
||||
else -> Log.debug(
|
||||
"[EmulationFragment] Surface cleared while emulation stopped."
|
||||
)
|
||||
}
|
||||
@@ -2093,29 +2248,35 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
}
|
||||
|
||||
private fun runWithValidSurface(programIndex: Int = 0) {
|
||||
NativeLibrary.surfaceChanged(surface)
|
||||
if (!emulationCanStart.invoke()) {
|
||||
return
|
||||
}
|
||||
val currentSurface = surface
|
||||
if (currentSurface == null || !currentSurface.isValid) {
|
||||
Log.debug("[EmulationFragment] runWithValidSurface called with invalid surface.")
|
||||
return
|
||||
}
|
||||
|
||||
when (state) {
|
||||
State.STOPPED -> {
|
||||
NativeLibrary.surfaceChanged(currentSurface)
|
||||
emulationThread = Thread({
|
||||
Log.debug("[EmulationFragment] Starting emulation thread.")
|
||||
NativeLibrary.run(gamePath, programIndex, true)
|
||||
}, "NativeEmulation")
|
||||
emulationThread.start()
|
||||
state = State.RUNNING
|
||||
}
|
||||
|
||||
State.PAUSED -> {
|
||||
Log.debug("[EmulationFragment] Resuming emulation.")
|
||||
NativeLibrary.unpauseEmulation()
|
||||
NativeLibrary.playTimeManagerStart()
|
||||
Log.debug(
|
||||
"[EmulationFragment] Surface restored while emulation paused; " +
|
||||
"waiting for explicit resume."
|
||||
)
|
||||
}
|
||||
|
||||
else -> Log.debug("[EmulationFragment] Bug, run called while already running.")
|
||||
}
|
||||
state = State.RUNNING
|
||||
}
|
||||
|
||||
private enum class State {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.fragments
|
||||
@@ -110,7 +110,7 @@ class FreedrenoSettingsFragment : Fragment() {
|
||||
val commonVars = listOf(
|
||||
"TU_DEBUG", "FD_MESA_DEBUG", "IR3_SHADER_DEBUG",
|
||||
"FD_RD_DUMP", "FD_RD_DUMP_FRAMES", "FD_RD_DUMP_TESTNAME",
|
||||
"TU_BREADCRUMBS"
|
||||
"TU_BREADCRUMBS", "FD_DEV_FEATURES"
|
||||
)
|
||||
|
||||
for (varName in commonVars) {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -6,11 +9,13 @@ package org.yuzu.yuzu_emu.fragments
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.databinding.DialogFolderPropertiesBinding
|
||||
import org.yuzu.yuzu_emu.model.DirectoryType
|
||||
import org.yuzu.yuzu_emu.model.GameDir
|
||||
import org.yuzu.yuzu_emu.model.GamesViewModel
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
@@ -25,14 +30,18 @@ class GameFolderPropertiesDialogFragment : DialogFragment() {
|
||||
val binding = DialogFolderPropertiesBinding.inflate(layoutInflater)
|
||||
val gameDir = requireArguments().parcelable<GameDir>(GAME_DIR)!!
|
||||
|
||||
// Restore checkbox state
|
||||
binding.deepScanSwitch.isChecked =
|
||||
savedInstanceState?.getBoolean(DEEP_SCAN) ?: gameDir.deepScan
|
||||
// Hide deepScan for external content, do automatically
|
||||
if (gameDir.type == DirectoryType.EXTERNAL_CONTENT) {
|
||||
binding.deepScanSwitch.visibility = View.GONE
|
||||
} else {
|
||||
// Restore checkbox state for game dirs
|
||||
binding.deepScanSwitch.isChecked =
|
||||
savedInstanceState?.getBoolean(DEEP_SCAN) ?: gameDir.deepScan
|
||||
|
||||
// Ensure that we can get the checkbox state even if the view is destroyed
|
||||
deepScan = binding.deepScanSwitch.isChecked
|
||||
binding.deepScanSwitch.setOnClickListener {
|
||||
deepScan = binding.deepScanSwitch.isChecked
|
||||
binding.deepScanSwitch.setOnClickListener {
|
||||
deepScan = binding.deepScanSwitch.isChecked
|
||||
}
|
||||
}
|
||||
|
||||
return MaterialAlertDialogBuilder(requireContext())
|
||||
@@ -41,8 +50,10 @@ class GameFolderPropertiesDialogFragment : DialogFragment() {
|
||||
.setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int ->
|
||||
val folderIndex = gamesViewModel.folders.value.indexOf(gameDir)
|
||||
if (folderIndex != -1) {
|
||||
gamesViewModel.folders.value[folderIndex].deepScan =
|
||||
binding.deepScanSwitch.isChecked
|
||||
if (gameDir.type == DirectoryType.GAME) {
|
||||
gamesViewModel.folders.value[folderIndex].deepScan =
|
||||
binding.deepScanSwitch.isChecked
|
||||
}
|
||||
gamesViewModel.updateGameDirs()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.fragments
|
||||
@@ -15,11 +15,14 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import kotlinx.coroutines.launch
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.adapters.FolderAdapter
|
||||
import org.yuzu.yuzu_emu.databinding.FragmentFoldersBinding
|
||||
import org.yuzu.yuzu_emu.model.DirectoryType
|
||||
import org.yuzu.yuzu_emu.model.GameDir
|
||||
import org.yuzu.yuzu_emu.model.GamesViewModel
|
||||
import org.yuzu.yuzu_emu.model.HomeViewModel
|
||||
import org.yuzu.yuzu_emu.ui.main.MainActivity
|
||||
@@ -73,7 +76,25 @@ class GameFoldersFragment : Fragment() {
|
||||
|
||||
val mainActivity = requireActivity() as MainActivity
|
||||
binding.buttonAdd.setOnClickListener {
|
||||
mainActivity.getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data)
|
||||
// Show a model to choose between Game and External Content
|
||||
val options = arrayOf(
|
||||
getString(R.string.games),
|
||||
getString(R.string.external_content)
|
||||
)
|
||||
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.add_folders)
|
||||
.setItems(options) { _, which ->
|
||||
when (which) {
|
||||
0 -> { // Game Folder
|
||||
mainActivity.getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data)
|
||||
}
|
||||
1 -> { // External Content Folder
|
||||
mainActivity.getExternalContentDirectory.launch(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
setInsets()
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.fragments
|
||||
|
||||
import android.Manifest
|
||||
@@ -114,6 +117,17 @@ class HomeSettingsFragment : Fragment() {
|
||||
}
|
||||
)
|
||||
)
|
||||
add(
|
||||
HomeSetting(
|
||||
R.string.profile_manager,
|
||||
R.string.profile_manager_description,
|
||||
R.drawable.ic_account_circle,
|
||||
{
|
||||
binding.root.findNavController()
|
||||
.navigate(R.id.action_homeSettingsFragment_to_profileManagerFragment)
|
||||
}
|
||||
)
|
||||
)
|
||||
add(
|
||||
HomeSetting(
|
||||
R.string.gpu_driver_manager,
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.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.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.adapters.ProfileAdapter
|
||||
import org.yuzu.yuzu_emu.databinding.FragmentProfileManagerBinding
|
||||
import org.yuzu.yuzu_emu.model.HomeViewModel
|
||||
import org.yuzu.yuzu_emu.model.UserProfile
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
|
||||
class ProfileManagerFragment : Fragment() {
|
||||
private var _binding: FragmentProfileManagerBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val homeViewModel: HomeViewModel by activityViewModels()
|
||||
private lateinit var profileAdapter: ProfileAdapter
|
||||
|
||||
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 = FragmentProfileManagerBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
homeViewModel.setStatusBarShadeVisibility(visible = false)
|
||||
|
||||
binding.toolbarProfiles.setNavigationOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
|
||||
setupRecyclerView()
|
||||
loadProfiles()
|
||||
|
||||
binding.buttonAddUser.setOnClickListener {
|
||||
if (NativeLibrary.canCreateUser()) {
|
||||
findNavController().navigate(R.id.action_profileManagerFragment_to_newUserDialog)
|
||||
} else {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.profile_max_users_title)
|
||||
.setMessage(R.string.profile_max_users_message)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
setInsets()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
loadProfiles()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
profileAdapter = ProfileAdapter(
|
||||
onProfileClick = { profile -> selectProfile(profile) },
|
||||
onEditClick = { profile -> editProfile(profile) },
|
||||
onDeleteClick = { profile -> confirmDeleteProfile(profile) }
|
||||
)
|
||||
binding.listProfiles.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = profileAdapter
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadProfiles() {
|
||||
val profiles = mutableListOf<UserProfile>()
|
||||
val userUUIDs = NativeLibrary.getAllUsers() ?: emptyArray()
|
||||
val currentUserUUID = NativeLibrary.getCurrentUser()
|
||||
|
||||
for (uuid in userUUIDs) {
|
||||
if (uuid.isNotEmpty()) {
|
||||
val username = NativeLibrary.getUserUsername(uuid)
|
||||
if (!username.isNullOrEmpty()) {
|
||||
val imagePath = NativeLibrary.getUserImagePath(uuid) ?: ""
|
||||
profiles.add(UserProfile(uuid, username, imagePath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
profileAdapter.submitList(profiles)
|
||||
profileAdapter.setCurrentUser(currentUserUUID ?: "")
|
||||
|
||||
binding.buttonAddUser.isEnabled = NativeLibrary.canCreateUser()
|
||||
}
|
||||
|
||||
private fun selectProfile(profile: UserProfile) {
|
||||
if (NativeLibrary.setCurrentUser(profile.uuid)) {
|
||||
loadProfiles()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun editProfile(profile: UserProfile) {
|
||||
val bundle = Bundle().apply {
|
||||
putString("uuid", profile.uuid)
|
||||
putString("username", profile.username)
|
||||
}
|
||||
findNavController().navigate(R.id.action_profileManagerFragment_to_newUserDialog, bundle)
|
||||
}
|
||||
|
||||
private fun confirmDeleteProfile(profile: UserProfile) {
|
||||
val currentUser = NativeLibrary.getCurrentUser()
|
||||
val isCurrentUser = profile.uuid == currentUser
|
||||
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.profile_delete_confirm_title)
|
||||
.setMessage(
|
||||
if (isCurrentUser) {
|
||||
getString(R.string.profile_delete_current_user_message, profile.username)
|
||||
} else {
|
||||
getString(R.string.profile_delete_confirm_message, profile.username)
|
||||
}
|
||||
)
|
||||
.setPositiveButton(R.string.profile_delete) { _, _ ->
|
||||
deleteProfile(profile)
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun deleteProfile(profile: UserProfile) {
|
||||
val currentUser = NativeLibrary.getCurrentUser()
|
||||
if (!currentUser.isNullOrEmpty() && profile.uuid == currentUser) {
|
||||
val users = NativeLibrary.getAllUsers() ?: emptyArray()
|
||||
for (uuid in users) {
|
||||
if (uuid.isNotEmpty() && uuid != profile.uuid) {
|
||||
NativeLibrary.setCurrentUser(uuid)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NativeLibrary.removeUser(profile.uuid)) {
|
||||
loadProfiles()
|
||||
}
|
||||
}
|
||||
|
||||
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 fabLayoutParams = binding.buttonAddUser.layoutParams as ViewGroup.MarginLayoutParams
|
||||
fabLayoutParams.leftMargin = leftInsets + 24
|
||||
fabLayoutParams.rightMargin = rightInsets + 24
|
||||
fabLayoutParams.bottomMargin = barInsets.bottom + 24
|
||||
binding.buttonAddUser.layoutParams = fabLayoutParams
|
||||
|
||||
windowInsets
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
NativeConfig.saveGlobalConfig()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -48,16 +51,68 @@ class AddonViewModel : ViewModel() {
|
||||
?: emptyArray()
|
||||
).toMutableList()
|
||||
patchList.sortBy { it.name }
|
||||
|
||||
// Ensure only one update is enabled
|
||||
ensureSingleUpdateEnabled(patchList)
|
||||
|
||||
removeDuplicates(patchList)
|
||||
|
||||
_patchList.value = patchList
|
||||
isRefreshing.set(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ensureSingleUpdateEnabled(patchList: MutableList<Patch>) {
|
||||
val updates = patchList.filter { PatchType.from(it.type) == PatchType.Update }
|
||||
if (updates.size <= 1) {
|
||||
return
|
||||
}
|
||||
|
||||
val enabledUpdates = updates.filter { it.enabled }
|
||||
|
||||
if (enabledUpdates.size > 1) {
|
||||
val nandOrSdmcEnabled = enabledUpdates.find {
|
||||
it.name.contains("(NAND)") || it.name.contains("(SDMC)")
|
||||
}
|
||||
|
||||
val updateToKeep = nandOrSdmcEnabled ?: enabledUpdates.first()
|
||||
|
||||
for (patch in patchList) {
|
||||
if (PatchType.from(patch.type) == PatchType.Update) {
|
||||
patch.enabled = (patch === updateToKeep)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeDuplicates(patchList: MutableList<Patch>) {
|
||||
val seen = mutableSetOf<String>()
|
||||
val iterator = patchList.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val patch = iterator.next()
|
||||
val key = "${patch.name}|${patch.version}|${patch.type}"
|
||||
if (seen.contains(key)) {
|
||||
iterator.remove()
|
||||
} else {
|
||||
seen.add(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setAddonToDelete(patch: Patch?) {
|
||||
_addonToDelete.value = patch
|
||||
}
|
||||
|
||||
fun enableOnlyThisUpdate(selectedPatch: Patch) {
|
||||
val currentList = _patchList.value
|
||||
for (patch in currentList) {
|
||||
if (PatchType.from(patch.type) == PatchType.Update) {
|
||||
patch.enabled = (patch === selectedPatch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onDeleteAddon(patch: Patch) {
|
||||
when (PatchType.from(patch.type)) {
|
||||
PatchType.Update -> NativeLibrary.removeUpdate(patch.programId)
|
||||
@@ -78,7 +133,17 @@ class AddonViewModel : ViewModel() {
|
||||
if (it.enabled) {
|
||||
null
|
||||
} else {
|
||||
it.name
|
||||
if (PatchType.from(it.type) == PatchType.Update) {
|
||||
if (it.name.contains("(NAND)") || it.name.contains("(SDMC)")) {
|
||||
it.name
|
||||
} else if (it.numericVersion != 0L) {
|
||||
"Update@${it.numericVersion}"
|
||||
} else {
|
||||
it.name
|
||||
}
|
||||
} else {
|
||||
it.name
|
||||
}
|
||||
}
|
||||
}.toTypedArray()
|
||||
)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -9,5 +12,14 @@ import kotlinx.parcelize.Parcelize
|
||||
@Parcelize
|
||||
data class GameDir(
|
||||
val uriString: String,
|
||||
var deepScan: Boolean
|
||||
) : Parcelable
|
||||
var deepScan: Boolean,
|
||||
val type: DirectoryType = DirectoryType.GAME
|
||||
) : Parcelable {
|
||||
// Needed for JNI backward compatability
|
||||
constructor(uriString: String, deepScan: Boolean) : this(uriString, deepScan, DirectoryType.GAME)
|
||||
}
|
||||
|
||||
enum class DirectoryType {
|
||||
GAME,
|
||||
EXTERNAL_CONTENT
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.model
|
||||
@@ -56,7 +56,7 @@ class GamesViewModel : ViewModel() {
|
||||
// Ensure keys are loaded so that ROM metadata can be decrypted.
|
||||
NativeLibrary.reloadKeys()
|
||||
|
||||
getGameDirs()
|
||||
getGameDirsAndExternalContent()
|
||||
reloadGames(directoriesChanged = false, firstStartup = true)
|
||||
}
|
||||
|
||||
@@ -144,11 +144,19 @@ class GamesViewModel : ViewModel() {
|
||||
fun addFolder(gameDir: GameDir, savedFromGameFragment: Boolean) =
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
NativeConfig.addGameDir(gameDir)
|
||||
val isFirstTimeSetup = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||
.getBoolean(org.yuzu.yuzu_emu.features.settings.model.Settings.PREF_FIRST_APP_LAUNCH, true)
|
||||
|
||||
getGameDirs(!isFirstTimeSetup)
|
||||
when (gameDir.type) {
|
||||
DirectoryType.GAME -> {
|
||||
NativeConfig.addGameDir(gameDir)
|
||||
val isFirstTimeSetup = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||
.getBoolean(org.yuzu.yuzu_emu.features.settings.model.Settings.PREF_FIRST_APP_LAUNCH, true)
|
||||
getGameDirsAndExternalContent(!isFirstTimeSetup)
|
||||
}
|
||||
DirectoryType.EXTERNAL_CONTENT -> {
|
||||
addExternalContentDir(gameDir.uriString)
|
||||
NativeConfig.saveGlobalConfig()
|
||||
getGameDirsAndExternalContent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (savedFromGameFragment) {
|
||||
@@ -168,8 +176,15 @@ class GamesViewModel : ViewModel() {
|
||||
val removedDirIndex = gameDirs.indexOf(gameDir)
|
||||
if (removedDirIndex != -1) {
|
||||
gameDirs.removeAt(removedDirIndex)
|
||||
NativeConfig.setGameDirs(gameDirs.toTypedArray())
|
||||
getGameDirs()
|
||||
when (gameDir.type) {
|
||||
DirectoryType.GAME -> {
|
||||
NativeConfig.setGameDirs(gameDirs.filter { it.type == DirectoryType.GAME }.toTypedArray())
|
||||
}
|
||||
DirectoryType.EXTERNAL_CONTENT -> {
|
||||
removeExternalContentDir(gameDir.uriString)
|
||||
}
|
||||
}
|
||||
getGameDirsAndExternalContent()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,15 +192,16 @@ class GamesViewModel : ViewModel() {
|
||||
fun updateGameDirs() =
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
NativeConfig.setGameDirs(_folders.value.toTypedArray())
|
||||
getGameDirs()
|
||||
val gameDirs = _folders.value.filter { it.type == DirectoryType.GAME }
|
||||
NativeConfig.setGameDirs(gameDirs.toTypedArray())
|
||||
getGameDirsAndExternalContent()
|
||||
}
|
||||
}
|
||||
|
||||
fun onOpenGameFoldersFragment() =
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
getGameDirs()
|
||||
getGameDirsAndExternalContent()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,16 +209,36 @@ class GamesViewModel : ViewModel() {
|
||||
NativeConfig.saveGlobalConfig()
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
getGameDirs(true)
|
||||
getGameDirsAndExternalContent(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGameDirs(reloadList: Boolean = false) {
|
||||
val gameDirs = NativeConfig.getGameDirs()
|
||||
_folders.value = gameDirs.toMutableList()
|
||||
private fun getGameDirsAndExternalContent(reloadList: Boolean = false) {
|
||||
val gameDirs = NativeConfig.getGameDirs().toMutableList()
|
||||
val externalContentDirs = NativeConfig.getExternalContentDirs().map {
|
||||
GameDir(it, false, DirectoryType.EXTERNAL_CONTENT)
|
||||
}
|
||||
gameDirs.addAll(externalContentDirs)
|
||||
_folders.value = gameDirs
|
||||
if (reloadList) {
|
||||
reloadGames(true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addExternalContentDir(path: String) {
|
||||
val currentDirs = NativeConfig.getExternalContentDirs().toMutableList()
|
||||
if (!currentDirs.contains(path)) {
|
||||
currentDirs.add(path)
|
||||
NativeConfig.setExternalContentDirs(currentDirs.toTypedArray())
|
||||
NativeConfig.saveGlobalConfig()
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeExternalContentDir(path: String) {
|
||||
val currentDirs = NativeConfig.getExternalContentDirs().toMutableList()
|
||||
currentDirs.remove(path)
|
||||
NativeConfig.setExternalContentDirs(currentDirs.toTypedArray())
|
||||
NativeConfig.saveGlobalConfig()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -12,5 +15,6 @@ data class Patch(
|
||||
val version: String,
|
||||
val type: Int,
|
||||
val programId: String,
|
||||
val titleId: String
|
||||
val titleId: String,
|
||||
val numericVersion: Long = 0
|
||||
)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class UserProfile(
|
||||
val uuid: String,
|
||||
val username: String,
|
||||
val imagePath: String = ""
|
||||
) : Parcelable
|
||||
|
||||
object ProfileUtils {
|
||||
fun generateRandomUUID(): String {
|
||||
val uuid = java.util.UUID.randomUUID()
|
||||
return uuid.toString().replace("-", "")
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.overlay
|
||||
@@ -20,7 +20,6 @@ import android.os.Looper
|
||||
import android.util.AttributeSet
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.MotionEvent
|
||||
import android.view.SurfaceView
|
||||
import android.view.View
|
||||
import android.view.View.OnTouchListener
|
||||
import android.view.WindowInsets
|
||||
@@ -42,10 +41,10 @@ import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
|
||||
/**
|
||||
* Draws the interactive input overlay on top of the
|
||||
* [SurfaceView] that is rendering emulation.
|
||||
* emulation rendering surface.
|
||||
*/
|
||||
class InputOverlay(context: Context, attrs: AttributeSet?) :
|
||||
SurfaceView(context, attrs),
|
||||
View(context, attrs),
|
||||
OnTouchListener {
|
||||
private val overlayButtons: MutableSet<InputOverlayDrawableButton> = HashSet()
|
||||
private val overlayDpads: MutableSet<InputOverlayDrawableDpad> = HashSet()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.ui
|
||||
@@ -13,6 +13,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.PopupMenu
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
@@ -27,10 +28,14 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
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.adapters.GameAdapter
|
||||
import org.yuzu.yuzu_emu.databinding.FragmentGamesBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
import org.yuzu.yuzu_emu.model.AppletInfo
|
||||
import org.yuzu.yuzu_emu.model.Game
|
||||
import org.yuzu.yuzu_emu.model.GamesViewModel
|
||||
import org.yuzu.yuzu_emu.model.HomeViewModel
|
||||
@@ -173,10 +178,16 @@ class GamesFragment : Fragment() {
|
||||
|
||||
setupTopView()
|
||||
|
||||
updateButtonsVisibility()
|
||||
|
||||
binding.addDirectory.setOnClickListener {
|
||||
getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data)
|
||||
}
|
||||
|
||||
binding.launchQlaunch?.setOnClickListener {
|
||||
launchQLaunch()
|
||||
}
|
||||
|
||||
setInsets()
|
||||
}
|
||||
|
||||
@@ -445,6 +456,47 @@ class GamesFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun launchQLaunch() {
|
||||
try {
|
||||
val appletPath = NativeLibrary.getAppletLaunchPath(AppletInfo.QLaunch.entryId)
|
||||
if (appletPath.isEmpty()) {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
R.string.applets_error_applet,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return
|
||||
}
|
||||
|
||||
NativeLibrary.setCurrentAppletId(AppletInfo.QLaunch.appletId)
|
||||
|
||||
val qlaunchGame = Game(
|
||||
title = getString(R.string.qlaunch_applet),
|
||||
path = appletPath
|
||||
)
|
||||
|
||||
val action = HomeNavigationDirections.actionGlobalEmulationActivity(qlaunchGame)
|
||||
findNavController().navigate(action)
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
"Failed to launch QLaunch: ${e.message}",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateButtonsVisibility() {
|
||||
val showQLaunch = BooleanSetting.ENABLE_QLAUNCH_BUTTON.getBoolean()
|
||||
val showFolder = BooleanSetting.ENABLE_FOLDER_BUTTON.getBoolean()
|
||||
val isFirmwareAvailable = NativeLibrary.isFirmwareAvailable()
|
||||
|
||||
val shouldShowQLaunch = showQLaunch && isFirmwareAvailable
|
||||
binding.launchQlaunch.visibility = if (shouldShowQLaunch) View.VISIBLE else View.GONE
|
||||
|
||||
binding.addDirectory.visibility = if (showFolder) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
private fun setInsets() =
|
||||
ViewCompat.setOnApplyWindowInsetsListener(
|
||||
binding.root
|
||||
@@ -498,6 +550,13 @@ class GamesFragment : Fragment() {
|
||||
mlpFab.rightMargin = rightInset + fabPadding
|
||||
binding.addDirectory.layoutParams = mlpFab
|
||||
|
||||
binding.launchQlaunch?.let { qlaunchButton ->
|
||||
val mlpQLaunch = qlaunchButton.layoutParams as ViewGroup.MarginLayoutParams
|
||||
mlpQLaunch.leftMargin = leftInset + fabPadding
|
||||
mlpQLaunch.bottomMargin = barInsets.bottom + fabPadding
|
||||
qlaunchButton.layoutParams = mlpQLaunch
|
||||
}
|
||||
|
||||
val navInsets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars())
|
||||
val gestureInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures())
|
||||
val bottomInset = maxOf(navInsets.bottom, gestureInsets.bottom, cutoutInsets.bottom)
|
||||
|
||||
@@ -63,6 +63,7 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
|
||||
class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
@@ -93,8 +94,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
|
||||
// Since Android 15, google automatically forces "games" to be 60 hrz
|
||||
// This ensures the display's max refresh rate is actually used
|
||||
display?.let {
|
||||
val supportedModes = it.supportedModes
|
||||
val maxRefreshRate = supportedModes.maxByOrNull { mode -> mode.refreshRate }
|
||||
@@ -199,8 +198,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
var artifact = tag
|
||||
// Nightly builds have a slightly different format
|
||||
if (NativeLibrary.isNightlyBuild()) {
|
||||
val splitTag = tag.split('.')
|
||||
artifact = splitTag.subList(1, splitTag.size - 1).joinToString(".")
|
||||
artifact = tag.substringAfter('.', tag)
|
||||
}
|
||||
downloadAndInstallUpdate(tag, artifact)
|
||||
}
|
||||
@@ -389,6 +387,13 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
}
|
||||
}
|
||||
|
||||
val getExternalContentDirectory =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { result ->
|
||||
if (result != null) {
|
||||
processExternalContentDir(result)
|
||||
}
|
||||
}
|
||||
|
||||
fun processGamesDir(result: Uri, calledFromGameFragment: Boolean = false) {
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result,
|
||||
@@ -410,6 +415,29 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
.show(supportFragmentManager, AddGameFolderDialogFragment.TAG)
|
||||
}
|
||||
|
||||
fun processExternalContentDir(result: Uri) {
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val uriString = result.toString()
|
||||
val folder = gamesViewModel.folders.value.firstOrNull {
|
||||
it.uriString == uriString && it.type == org.yuzu.yuzu_emu.model.DirectoryType.EXTERNAL_CONTENT
|
||||
}
|
||||
if (folder != null) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
R.string.folder_already_added,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return
|
||||
}
|
||||
|
||||
val externalContentDir = org.yuzu.yuzu_emu.model.GameDir(uriString, false, org.yuzu.yuzu_emu.model.DirectoryType.EXTERNAL_CONTENT)
|
||||
gamesViewModel.addFolder(externalContentDir, savedFromGameFragment = false)
|
||||
}
|
||||
|
||||
val getProdKey = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
processKey(result, "keys")
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import android.view.InputDevice
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import androidx.activity.ComponentActivity
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
object ControllerNavigationGlobalHook {
|
||||
private val installed = AtomicBoolean(false)
|
||||
|
||||
fun install(application: Application) {
|
||||
if (!installed.compareAndSet(false, true)) {
|
||||
return
|
||||
}
|
||||
application.registerActivityLifecycleCallbacks(HookInstaller)
|
||||
}
|
||||
|
||||
private object HookInstaller : Application.ActivityLifecycleCallbacks {
|
||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||
installHookIfNeeded(activity)
|
||||
}
|
||||
|
||||
override fun onActivityResumed(activity: Activity) {
|
||||
installHookIfNeeded(activity)
|
||||
}
|
||||
|
||||
override fun onActivityStarted(activity: Activity) = Unit
|
||||
override fun onActivityPaused(activity: Activity) = Unit
|
||||
override fun onActivityStopped(activity: Activity) = Unit
|
||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit
|
||||
override fun onActivityDestroyed(activity: Activity) = Unit
|
||||
}
|
||||
|
||||
private fun installHookIfNeeded(activity: Activity) {
|
||||
val window = activity.window ?: return
|
||||
val currentCallback = window.callback ?: return
|
||||
if (currentCallback is ControllerNavigationWindowCallback) {
|
||||
return
|
||||
}
|
||||
window.callback = ControllerNavigationWindowCallback(activity, currentCallback)
|
||||
}
|
||||
|
||||
private class ControllerNavigationWindowCallback(
|
||||
private val activity: Activity,
|
||||
private val delegate: Window.Callback
|
||||
) : Window.Callback by delegate {
|
||||
private val componentActivity = activity as? ComponentActivity
|
||||
|
||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||
if (activity.isFinishing || activity.isDestroyed) {
|
||||
return delegate.dispatchKeyEvent(event)
|
||||
}
|
||||
|
||||
if (!BooleanSetting.INVERT_CONFIRM_BACK_CONTROLLER_BUTTONS.getBoolean()) {
|
||||
return delegate.dispatchKeyEvent(event)
|
||||
}
|
||||
|
||||
if (!isControllerInput(event) || componentActivity == null) {
|
||||
return delegate.dispatchKeyEvent(event)
|
||||
}
|
||||
if (shouldBypassInGameplay()) {
|
||||
return delegate.dispatchKeyEvent(event)
|
||||
}
|
||||
|
||||
if (isConfirmAction(event.keyCode)) {
|
||||
return when (event.action) {
|
||||
KeyEvent.ACTION_DOWN -> {
|
||||
if (event.repeatCount == 0) {
|
||||
componentActivity.onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
true
|
||||
}
|
||||
KeyEvent.ACTION_UP -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
if (isBackAction(event.keyCode)) {
|
||||
val remappedEvent = KeyEvent(
|
||||
event.downTime,
|
||||
event.eventTime,
|
||||
event.action,
|
||||
KeyEvent.KEYCODE_DPAD_CENTER,
|
||||
event.repeatCount,
|
||||
event.metaState,
|
||||
event.deviceId,
|
||||
event.scanCode,
|
||||
event.flags,
|
||||
event.source
|
||||
)
|
||||
return delegate.dispatchKeyEvent(remappedEvent)
|
||||
}
|
||||
|
||||
return delegate.dispatchKeyEvent(event)
|
||||
}
|
||||
|
||||
private fun shouldBypassInGameplay(): Boolean {
|
||||
if (activity.javaClass.name != "org.yuzu.yuzu_emu.activities.EmulationActivity") {
|
||||
return false
|
||||
}
|
||||
if (!NativeLibrary.isRunning()) {
|
||||
return false
|
||||
}
|
||||
|
||||
val surface = activity.findViewById<View?>(R.id.surface_emulation) ?: return false
|
||||
if (!surface.isShown || surface.visibility != View.VISIBLE) {
|
||||
return false
|
||||
}
|
||||
|
||||
val focused = activity.currentFocus
|
||||
if (focused != null) {
|
||||
val inputOverlay = activity.findViewById<View?>(R.id.surface_input_overlay)
|
||||
if (!isDescendantOf(focused, inputOverlay)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isDescendantOf(view: View, parent: View?): Boolean {
|
||||
if (parent == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
var current: View? = view
|
||||
while (current != null) {
|
||||
if (current === parent) {
|
||||
return true
|
||||
}
|
||||
current = current.parent as? View
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun isControllerInput(event: KeyEvent): Boolean {
|
||||
val source = event.source
|
||||
val deviceSources = event.device?.sources ?: InputDevice.getDevice(event.deviceId)?.sources ?: 0
|
||||
return hasControllerSource(source) || hasControllerSource(deviceSources)
|
||||
}
|
||||
|
||||
private fun isConfirmAction(keyCode: Int): Boolean {
|
||||
return keyCode == KeyEvent.KEYCODE_BUTTON_A
|
||||
}
|
||||
|
||||
private fun isBackAction(keyCode: Int): Boolean {
|
||||
return keyCode == KeyEvent.KEYCODE_BUTTON_B
|
||||
}
|
||||
|
||||
private fun hasControllerSource(source: Int): Boolean {
|
||||
return source and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD ||
|
||||
source and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK ||
|
||||
source and InputDevice.SOURCE_DPAD == InputDevice.SOURCE_DPAD
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.utils
|
||||
@@ -25,6 +25,7 @@ object DirectoryInitialization {
|
||||
initializeInternalStorage()
|
||||
NativeLibrary.initializeSystem(false)
|
||||
NativeConfig.initializeGlobalConfig()
|
||||
NativeLibrary.reloadProfiles()
|
||||
migrateSettings()
|
||||
areDirectoriesReady = true
|
||||
}
|
||||
@@ -60,6 +61,12 @@ object DirectoryInitialization {
|
||||
saveConfig = true
|
||||
}
|
||||
|
||||
val staticThemeColor = preferences.migratePreference<Int>(Settings.PREF_STATIC_THEME_COLOR)
|
||||
if (staticThemeColor != null) {
|
||||
IntSetting.STATIC_THEME_COLOR.setInt(staticThemeColor)
|
||||
saveConfig = true
|
||||
}
|
||||
|
||||
val blackBackgrounds =
|
||||
preferences.migratePreference<Boolean>(Settings.PREF_BLACK_BACKGROUNDS)
|
||||
if (blackBackgrounds != null) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.utils
|
||||
|
||||
import android.content.SharedPreferences
|
||||
@@ -49,15 +49,42 @@ object GameHelper {
|
||||
// Remove previous filesystem provider information so we can get up to date version info
|
||||
NativeLibrary.clearFilesystemProvider()
|
||||
|
||||
// Scan External Content directories and register all NSP/XCI files
|
||||
val externalContentDirs = NativeConfig.getExternalContentDirs()
|
||||
val uniqueExternalContentDirs = linkedSetOf<String>()
|
||||
externalContentDirs.forEach { externalDir ->
|
||||
if (externalDir.isNotEmpty()) {
|
||||
uniqueExternalContentDirs.add(externalDir)
|
||||
}
|
||||
}
|
||||
|
||||
val mountedContainerUris = mutableSetOf<String>()
|
||||
for (externalDir in uniqueExternalContentDirs) {
|
||||
if (externalDir.isNotEmpty()) {
|
||||
val externalDirUri = externalDir.toUri()
|
||||
if (FileUtil.isTreeUriValid(externalDirUri)) {
|
||||
scanContentContainersRecursive(FileUtil.listFiles(externalDirUri), 3) {
|
||||
val containerUri = it.uri.toString()
|
||||
if (mountedContainerUris.add(containerUri)) {
|
||||
NativeLibrary.addFileToFilesystemProvider(containerUri)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val badDirs = mutableListOf<Int>()
|
||||
gameDirs.forEachIndexed { index: Int, gameDir: GameDir ->
|
||||
val gameDirUri = gameDir.uriString.toUri()
|
||||
val isValid = FileUtil.isTreeUriValid(gameDirUri)
|
||||
if (isValid) {
|
||||
val scanDepth = if (gameDir.deepScan) 3 else 1
|
||||
|
||||
addGamesRecursive(
|
||||
games,
|
||||
FileUtil.listFiles(gameDirUri),
|
||||
if (gameDir.deepScan) 3 else 1
|
||||
scanDepth,
|
||||
mountedContainerUris
|
||||
)
|
||||
} else {
|
||||
badDirs.add(index)
|
||||
@@ -88,10 +115,40 @@ object GameHelper {
|
||||
return games.toList()
|
||||
}
|
||||
|
||||
// File extensions considered as external content, buuut should
|
||||
// be done better imo.
|
||||
private val externalContentExtensions = setOf("nsp", "xci")
|
||||
|
||||
private fun scanContentContainersRecursive(
|
||||
files: Array<MinimalDocumentFile>,
|
||||
depth: Int,
|
||||
onContainerFound: (MinimalDocumentFile) -> Unit
|
||||
) {
|
||||
if (depth <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
files.forEach {
|
||||
if (it.isDirectory) {
|
||||
scanContentContainersRecursive(
|
||||
FileUtil.listFiles(it.uri),
|
||||
depth - 1,
|
||||
onContainerFound
|
||||
)
|
||||
} else {
|
||||
val extension = FileUtil.getExtension(it.uri).lowercase()
|
||||
if (externalContentExtensions.contains(extension)) {
|
||||
onContainerFound(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addGamesRecursive(
|
||||
games: MutableList<Game>,
|
||||
files: Array<MinimalDocumentFile>,
|
||||
depth: Int
|
||||
depth: Int,
|
||||
mountedContainerUris: MutableSet<String>
|
||||
) {
|
||||
if (depth <= 0) {
|
||||
return
|
||||
@@ -102,11 +159,20 @@ object GameHelper {
|
||||
addGamesRecursive(
|
||||
games,
|
||||
FileUtil.listFiles(it.uri),
|
||||
depth - 1
|
||||
depth - 1,
|
||||
mountedContainerUris
|
||||
)
|
||||
} else {
|
||||
if (Game.extensions.contains(FileUtil.getExtension(it.uri))) {
|
||||
val game = getGame(it.uri, true)
|
||||
val extension = FileUtil.getExtension(it.uri).lowercase()
|
||||
val filePath = it.uri.toString()
|
||||
|
||||
if (externalContentExtensions.contains(extension) &&
|
||||
mountedContainerUris.add(filePath)) {
|
||||
NativeLibrary.addGameFolderFileToFilesystemProvider(filePath)
|
||||
}
|
||||
|
||||
if (Game.extensions.contains(extension)) {
|
||||
val game = getGame(it.uri, true, false)
|
||||
if (game != null) {
|
||||
games.add(game)
|
||||
}
|
||||
@@ -115,14 +181,20 @@ object GameHelper {
|
||||
}
|
||||
}
|
||||
|
||||
fun getGame(uri: Uri, addedToLibrary: Boolean): Game? {
|
||||
fun getGame(
|
||||
uri: Uri,
|
||||
addedToLibrary: Boolean,
|
||||
registerFilesystemProvider: Boolean = true
|
||||
): Game? {
|
||||
val filePath = uri.toString()
|
||||
if (!GameMetadata.getIsValid(filePath)) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Needed to update installed content information
|
||||
NativeLibrary.addFileToFilesystemProvider(filePath)
|
||||
if (registerFilesystemProvider) {
|
||||
// Needed to update installed content information
|
||||
NativeLibrary.addFileToFilesystemProvider(filePath)
|
||||
}
|
||||
|
||||
var name = GameMetadata.getTitle(filePath)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
@@ -204,4 +204,12 @@ object NativeConfig {
|
||||
external fun getSdmcDir(): String
|
||||
@Synchronized
|
||||
external fun setSdmcDir(path: String)
|
||||
|
||||
/**
|
||||
* External Content Provider
|
||||
*/
|
||||
@Synchronized
|
||||
external fun getExternalContentDirs(): Array<String>
|
||||
@Synchronized
|
||||
external fun setExternalContentDirs(dirs: Array<String>)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.utils
|
||||
@@ -144,6 +144,15 @@ object FreedrenoPresets {
|
||||
)
|
||||
)
|
||||
|
||||
val DEV_FEATURES_UBWC_HINT = FreedrenoPreset(
|
||||
name = "Dev - UBWC Flag Hint",
|
||||
description = "Enable TP UBWC flag hint for development",
|
||||
icon = "ic_dev_features",
|
||||
variables = mapOf(
|
||||
"FD_DEV_FEATURES" to "enable_tp_ubwc_flag_hint=1"
|
||||
)
|
||||
)
|
||||
|
||||
val PERFORMANCE_DEFAULT = FreedrenoPreset(
|
||||
name = "Performance - Default",
|
||||
description = "Clear all debug options for performance",
|
||||
@@ -159,6 +168,7 @@ object FreedrenoPresets {
|
||||
CAPTURE_FRAMES,
|
||||
SHADER_DEBUG,
|
||||
GPU_HANG_TRACE,
|
||||
DEV_FEATURES_UBWC_HINT,
|
||||
PERFORMANCE_DEFAULT
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.utils
|
||||
@@ -80,16 +80,14 @@ object PathUtil {
|
||||
}
|
||||
}
|
||||
|
||||
// This really shouldn't be necessary, but the Android API seemingly
|
||||
// doesn't have a way of doing this?
|
||||
// Apparently, on certain devices the mount location can vary, so add
|
||||
// extra cases here if we discover any new ones.
|
||||
fun getRemovableStoragePath(idString: String): String? {
|
||||
var pathFile: File
|
||||
val possibleMountPaths = listOf("/mnt/media_rw/$idString", "/storage/$idString")
|
||||
|
||||
pathFile = File("/mnt/media_rw/$idString");
|
||||
if (pathFile.exists()) {
|
||||
return pathFile.absolutePath
|
||||
for (mountPath in possibleMountPaths) {
|
||||
val pathFile = File(mountPath);
|
||||
if (pathFile.exists()) {
|
||||
return pathFile.absolutePath
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.utils
|
||||
@@ -52,7 +52,7 @@ object ThemeHelper {
|
||||
}
|
||||
|
||||
private fun getSelectedStaticThemeColor(): Int {
|
||||
val themeIndex = preferences.getInt(Settings.PREF_STATIC_THEME_COLOR, 0)
|
||||
val themeIndex = IntSetting.STATIC_THEME_COLOR.getInt(false)
|
||||
val themes = arrayOf(
|
||||
R.style.Theme_Eden_Main,
|
||||
R.style.Theme_Yuzu_Main_Violet,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
@@ -11,8 +11,7 @@ import android.graphics.*
|
||||
import android.util.AttributeSet
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import androidx.preference.PreferenceManager
|
||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||
|
||||
class GradientBorderCardView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
@@ -44,12 +43,7 @@ class GradientBorderCardView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
private fun updateThemeState() {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val themeIndex = try {
|
||||
prefs.getInt(Settings.PREF_STATIC_THEME_COLOR, 0)
|
||||
} catch (e: Exception) {
|
||||
0 // Default to Eden theme if error
|
||||
}
|
||||
val themeIndex = IntSetting.STATIC_THEME_COLOR.getInt(false)
|
||||
isEdenTheme = themeIndex == 0
|
||||
invalidate()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
@@ -27,10 +27,7 @@ if (ARCHITECTURE_arm64)
|
||||
target_link_libraries(yuzu-android PRIVATE adrenotools)
|
||||
endif()
|
||||
|
||||
if (ENABLE_OPENSSL OR ENABLE_WEB_SERVICE)
|
||||
target_link_libraries(yuzu-android PRIVATE OpenSSL::SSL cpp-jwt::cpp-jwt)
|
||||
endif()
|
||||
|
||||
target_link_libraries(yuzu-android PRIVATE OpenSSL::SSL cpp-jwt::cpp-jwt)
|
||||
if (ENABLE_UPDATE_CHECKER)
|
||||
target_compile_definitions(yuzu-android PUBLIC ENABLE_UPDATE_CHECKER)
|
||||
endif()
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <common/fs/path_util.h>
|
||||
#include <common/logging/log.h>
|
||||
#include <common/settings.h>
|
||||
#include <input_common/main.h>
|
||||
#include "android_config.h"
|
||||
#include "android_settings.h"
|
||||
@@ -32,6 +33,12 @@ void AndroidConfig::ReadAndroidValues() {
|
||||
if (global) {
|
||||
ReadAndroidUIValues();
|
||||
ReadUIValues();
|
||||
BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage));
|
||||
Settings::values.ext_content_from_game_dirs = ReadBooleanSetting(
|
||||
std::string("ext_content_from_game_dirs"),
|
||||
std::make_optional(
|
||||
Settings::values.ext_content_from_game_dirs.GetDefault()));
|
||||
EndGroup();
|
||||
ReadOverlayValues();
|
||||
}
|
||||
ReadDriverValues();
|
||||
@@ -69,6 +76,18 @@ void AndroidConfig::ReadPathValues() {
|
||||
}
|
||||
EndArray();
|
||||
|
||||
// Read external content directories
|
||||
Settings::values.external_content_dirs.clear();
|
||||
const int external_dirs_size = BeginArray(std::string("external_content_dirs"));
|
||||
for (int i = 0; i < external_dirs_size; ++i) {
|
||||
SetArrayIndex(i);
|
||||
std::string dir_path = ReadStringSetting(std::string("path"));
|
||||
if (!dir_path.empty()) {
|
||||
Settings::values.external_content_dirs.push_back(dir_path);
|
||||
}
|
||||
}
|
||||
EndArray();
|
||||
|
||||
const auto nand_dir_setting = ReadStringSetting(std::string("nand_directory"));
|
||||
if (!nand_dir_setting.empty()) {
|
||||
Common::FS::SetEdenPath(Common::FS::EdenPath::NANDDir, nand_dir_setting);
|
||||
@@ -241,6 +260,14 @@ void AndroidConfig::SavePathValues() {
|
||||
}
|
||||
EndArray();
|
||||
|
||||
// Save external content directories
|
||||
BeginArray(std::string("external_content_dirs"));
|
||||
for (size_t i = 0; i < Settings::values.external_content_dirs.size(); ++i) {
|
||||
SetArrayIndex(i);
|
||||
WriteStringSetting(std::string("path"), Settings::values.external_content_dirs[i]);
|
||||
}
|
||||
EndArray();
|
||||
|
||||
// Save custom NAND directory
|
||||
const auto nand_path = Common::FS::GetEdenPathString(Common::FS::EdenPath::NANDDir);
|
||||
WriteStringSetting(std::string("nand_directory"), nand_path,
|
||||
|
||||
@@ -54,17 +54,20 @@ namespace AndroidSettings {
|
||||
Settings::SwitchableSetting<std::string, false> driver_path{linkage, "", "driver_path",
|
||||
Settings::Category::GpuDriver};
|
||||
|
||||
// LRU Cache
|
||||
Settings::SwitchableSetting<bool> use_lru_cache{linkage, true, "use_lru_cache",
|
||||
Settings::Category::System};
|
||||
|
||||
Settings::Setting<s32> theme{linkage, 0, "theme", Settings::Category::Android};
|
||||
Settings::Setting<s32> theme_mode{linkage, -1, "theme_mode", Settings::Category::Android};
|
||||
Settings::Setting<s32> static_theme_color{linkage, 5, "static_theme_color", Settings::Category::Android};
|
||||
Settings::Setting<bool> black_backgrounds{linkage, false, "black_backgrounds",
|
||||
Settings::Category::Android};
|
||||
Settings::Setting<s32> app_language{linkage, 0, "app_language", Settings::Category::Android};
|
||||
Settings::Setting<bool> enable_update_checks{linkage, true, "enable_update_checks",
|
||||
Settings::Category::Android};
|
||||
Settings::Setting<bool> enable_folder_button{linkage, true, "enable_folder_button",
|
||||
Settings::Category::Android};
|
||||
Settings::Setting<bool> enable_qlaunch_button{linkage, false, "enable_qlaunch_button",
|
||||
Settings::Category::Android};
|
||||
Settings::Setting<bool> invert_confirm_back_controller_buttons{
|
||||
linkage, false, "invert_confirm_back_controller_buttons", Settings::Category::Android};
|
||||
|
||||
// Input/performance overlay settings
|
||||
std::vector<OverlayControlData> overlay_control_data;
|
||||
@@ -198,9 +201,14 @@ namespace AndroidSettings {
|
||||
Settings::Specialization::Default, true, true,
|
||||
&show_soc_overlay};
|
||||
|
||||
// MISC
|
||||
Settings::Setting<bool> dont_show_driver_shader_warning{linkage, false,
|
||||
"dont_show_driver_shader_warning",
|
||||
Settings::Category::Android, Settings::Specialization::Default, true, true};
|
||||
Settings::Setting<bool> enable_quick_settings{linkage, true,
|
||||
"enable_quick_settings",
|
||||
Settings::Category::Android, Settings::Specialization::Default, true,
|
||||
false};
|
||||
};
|
||||
|
||||
extern Values values;
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "common/android/id_cache.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "input_common/drivers/android.h"
|
||||
#include "input_common/drivers/touch_screen.h"
|
||||
#include "input_common/drivers/virtual_amiibo.h"
|
||||
@@ -14,6 +24,20 @@
|
||||
#include "jni/native.h"
|
||||
|
||||
void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
|
||||
if (!surface) {
|
||||
LOG_INFO(Frontend, "EmuWindow_Android::OnSurfaceChanged received null surface");
|
||||
m_window_width = 0;
|
||||
m_window_height = 0;
|
||||
window_info.render_surface = nullptr;
|
||||
m_last_frame_rate_hint = -1.0f;
|
||||
m_pending_frame_rate_hint = -1.0f;
|
||||
m_pending_frame_rate_hint_votes = 0;
|
||||
m_smoothed_present_rate = 0.0f;
|
||||
m_last_frame_display_time = {};
|
||||
m_pending_frame_rate_since = {};
|
||||
return;
|
||||
}
|
||||
|
||||
m_window_width = ANativeWindow_getWidth(surface);
|
||||
m_window_height = ANativeWindow_getHeight(surface);
|
||||
|
||||
@@ -21,6 +45,7 @@ void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
|
||||
UpdateCurrentFramebufferLayout(m_window_width, m_window_height);
|
||||
|
||||
window_info.render_surface = reinterpret_cast<void*>(surface);
|
||||
UpdateFrameRateHint();
|
||||
}
|
||||
|
||||
void EmuWindow_Android::OnTouchPressed(int id, float x, float y) {
|
||||
@@ -40,6 +65,9 @@ void EmuWindow_Android::OnTouchReleased(int id) {
|
||||
}
|
||||
|
||||
void EmuWindow_Android::OnFrameDisplayed() {
|
||||
UpdateObservedFrameRate();
|
||||
UpdateFrameRateHint();
|
||||
|
||||
if (!m_first_frame) {
|
||||
Common::Android::RunJNIOnFiber<void>(
|
||||
[&](JNIEnv* env) { EmulationSession::GetInstance().OnEmulationStarted(); });
|
||||
@@ -47,6 +75,175 @@ void EmuWindow_Android::OnFrameDisplayed() {
|
||||
}
|
||||
}
|
||||
|
||||
void EmuWindow_Android::UpdateObservedFrameRate() {
|
||||
const auto now = Clock::now();
|
||||
if (m_last_frame_display_time.time_since_epoch().count() != 0) {
|
||||
const auto frame_time = std::chrono::duration<float>(now - m_last_frame_display_time);
|
||||
const float seconds = frame_time.count();
|
||||
if (seconds > 0.0f) {
|
||||
const float instantaneous_rate = 1.0f / seconds;
|
||||
if (std::isfinite(instantaneous_rate) && instantaneous_rate >= 1.0f &&
|
||||
instantaneous_rate <= 240.0f) {
|
||||
constexpr float SmoothingFactor = 0.15f;
|
||||
if (m_smoothed_present_rate <= 0.0f) {
|
||||
m_smoothed_present_rate = instantaneous_rate;
|
||||
} else {
|
||||
m_smoothed_present_rate +=
|
||||
(instantaneous_rate - m_smoothed_present_rate) * SmoothingFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_last_frame_display_time = now;
|
||||
}
|
||||
|
||||
float EmuWindow_Android::QuantizeFrameRateHint(float frame_rate) {
|
||||
if (!std::isfinite(frame_rate) || frame_rate <= 0.0f) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
frame_rate = std::clamp(frame_rate, 1.0f, 240.0f);
|
||||
|
||||
constexpr float Step = 0.5f;
|
||||
return std::round(frame_rate / Step) * Step;
|
||||
}
|
||||
|
||||
float EmuWindow_Android::GetFrameTimeVerifiedHint() const {
|
||||
if (!EmulationSession::GetInstance().IsRunning()) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
const double frame_time_scale =
|
||||
EmulationSession::GetInstance().System().GetPerfStats().GetLastFrameTimeScale();
|
||||
if (!std::isfinite(frame_time_scale) || frame_time_scale <= 0.0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
const float verified_rate =
|
||||
std::clamp(60.0f / static_cast<float>(frame_time_scale), 0.0f, 240.0f);
|
||||
return QuantizeFrameRateHint(verified_rate);
|
||||
}
|
||||
|
||||
float EmuWindow_Android::GetFrameRateHint() const {
|
||||
const float observed_rate = std::clamp(m_smoothed_present_rate, 0.0f, 240.0f);
|
||||
const float frame_time_verified_hint = GetFrameTimeVerifiedHint();
|
||||
|
||||
if (m_last_frame_rate_hint > 0.0f && observed_rate > 0.0f) {
|
||||
const float tolerance = std::max(m_last_frame_rate_hint * 0.12f, 4.0f);
|
||||
if (std::fabs(observed_rate - m_last_frame_rate_hint) <= tolerance) {
|
||||
return m_last_frame_rate_hint;
|
||||
}
|
||||
}
|
||||
|
||||
const float observed_hint = QuantizeFrameRateHint(observed_rate);
|
||||
if (observed_hint > 0.0f) {
|
||||
if (frame_time_verified_hint > 0.0f) {
|
||||
const float tolerance = std::max(observed_hint * 0.20f, 3.0f);
|
||||
if (std::fabs(observed_hint - frame_time_verified_hint) <= tolerance) {
|
||||
return QuantizeFrameRateHint((observed_hint + frame_time_verified_hint) * 0.5f);
|
||||
}
|
||||
}
|
||||
return observed_hint;
|
||||
}
|
||||
|
||||
if (frame_time_verified_hint > 0.0f) {
|
||||
return frame_time_verified_hint;
|
||||
}
|
||||
|
||||
constexpr float NominalFrameRate = 60.0f;
|
||||
if (!Settings::values.use_speed_limit.GetValue()) {
|
||||
return NominalFrameRate;
|
||||
}
|
||||
|
||||
const u16 speed_limit = Settings::SpeedLimit();
|
||||
if (speed_limit == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
const float speed_limited_rate =
|
||||
NominalFrameRate * (static_cast<float>(std::min<u16>(speed_limit, 100)) / 100.0f);
|
||||
return QuantizeFrameRateHint(speed_limited_rate);
|
||||
}
|
||||
|
||||
void EmuWindow_Android::UpdateFrameRateHint() {
|
||||
auto* const surface = reinterpret_cast<ANativeWindow*>(window_info.render_surface);
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto now = Clock::now();
|
||||
const float frame_rate_hint = GetFrameRateHint();
|
||||
if (std::fabs(frame_rate_hint - m_last_frame_rate_hint) < 0.01f) {
|
||||
m_pending_frame_rate_hint = frame_rate_hint;
|
||||
m_pending_frame_rate_hint_votes = 0;
|
||||
m_pending_frame_rate_since = {};
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame_rate_hint == 0.0f) {
|
||||
m_pending_frame_rate_hint = frame_rate_hint;
|
||||
m_pending_frame_rate_hint_votes = 0;
|
||||
m_pending_frame_rate_since = now;
|
||||
} else if (m_last_frame_rate_hint >= 0.0f) {
|
||||
if (std::fabs(frame_rate_hint - m_pending_frame_rate_hint) >= 0.01f) {
|
||||
m_pending_frame_rate_hint = frame_rate_hint;
|
||||
m_pending_frame_rate_hint_votes = 1;
|
||||
m_pending_frame_rate_since = now;
|
||||
return;
|
||||
}
|
||||
|
||||
++m_pending_frame_rate_hint_votes;
|
||||
if (m_pending_frame_rate_since.time_since_epoch().count() == 0) {
|
||||
m_pending_frame_rate_since = now;
|
||||
}
|
||||
|
||||
const auto stable_for = now - m_pending_frame_rate_since;
|
||||
const float reference_rate = std::max(frame_rate_hint, 1.0f);
|
||||
const auto stable_duration = std::chrono::duration_cast<Clock::duration>(
|
||||
std::chrono::duration<float>(std::clamp(3.0f / reference_rate, 0.15f, 0.40f)));
|
||||
constexpr std::uint32_t MinStableVotes = 3;
|
||||
|
||||
if (m_pending_frame_rate_hint_votes < MinStableVotes || stable_for < stable_duration) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
m_pending_frame_rate_since = now;
|
||||
}
|
||||
|
||||
using SetFrameRateWithChangeStrategyFn =
|
||||
int32_t (*)(ANativeWindow*, float, int8_t, int8_t);
|
||||
using SetFrameRateFn = int32_t (*)(ANativeWindow*, float, int8_t);
|
||||
static const auto set_frame_rate_with_change_strategy =
|
||||
reinterpret_cast<SetFrameRateWithChangeStrategyFn>(
|
||||
dlsym(RTLD_DEFAULT, "ANativeWindow_setFrameRateWithChangeStrategy"));
|
||||
static const auto set_frame_rate = reinterpret_cast<SetFrameRateFn>(
|
||||
dlsym(RTLD_DEFAULT, "ANativeWindow_setFrameRate"));
|
||||
|
||||
constexpr int8_t FrameRateCompatibilityDefault = 0;
|
||||
constexpr int8_t ChangeFrameRateOnlyIfSeamless = 0;
|
||||
|
||||
int32_t result = -1;
|
||||
if (set_frame_rate_with_change_strategy) {
|
||||
result = set_frame_rate_with_change_strategy(surface, frame_rate_hint,
|
||||
FrameRateCompatibilityDefault,
|
||||
ChangeFrameRateOnlyIfSeamless);
|
||||
} else if (set_frame_rate) {
|
||||
result = set_frame_rate(surface, frame_rate_hint, FrameRateCompatibilityDefault);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
LOG_DEBUG(Frontend, "Failed to update Android surface frame rate hint: {}", result);
|
||||
return;
|
||||
}
|
||||
|
||||
m_last_frame_rate_hint = frame_rate_hint;
|
||||
m_pending_frame_rate_hint = frame_rate_hint;
|
||||
m_pending_frame_rate_hint_votes = 0;
|
||||
m_pending_frame_rate_since = {};
|
||||
}
|
||||
|
||||
EmuWindow_Android::EmuWindow_Android(ANativeWindow* surface,
|
||||
std::shared_ptr<Common::DynamicLibrary> driver_library)
|
||||
: m_driver_library{driver_library} {
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
|
||||
@@ -50,10 +55,24 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
using Clock = std::chrono::steady_clock;
|
||||
|
||||
void UpdateFrameRateHint();
|
||||
void UpdateObservedFrameRate();
|
||||
[[nodiscard]] float GetFrameRateHint() const;
|
||||
[[nodiscard]] float GetFrameTimeVerifiedHint() const;
|
||||
[[nodiscard]] static float QuantizeFrameRateHint(float frame_rate);
|
||||
|
||||
float m_window_width{};
|
||||
float m_window_height{};
|
||||
|
||||
std::shared_ptr<Common::DynamicLibrary> m_driver_library;
|
||||
|
||||
bool m_first_frame = false;
|
||||
float m_last_frame_rate_hint = -1.0f;
|
||||
float m_pending_frame_rate_hint = -1.0f;
|
||||
float m_smoothed_present_rate = 0.0f;
|
||||
Clock::time_point m_last_frame_display_time{};
|
||||
Clock::time_point m_pending_frame_rate_since{};
|
||||
std::uint32_t m_pending_frame_rate_hint_votes = 0;
|
||||
};
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -18,7 +21,7 @@ struct RomMetadata {
|
||||
bool isHomebrew;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, RomMetadata> m_rom_metadata_cache;
|
||||
ankerl::unordered_dense::map<std::string, RomMetadata> m_rom_metadata_cache;
|
||||
|
||||
RomMetadata CacheRomMetadata(const std::string& path) {
|
||||
const auto file =
|
||||
@@ -93,6 +96,11 @@ jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobj
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((file_type == Loader::FileType::NSP || file_type == Loader::FileType::XCI) &&
|
||||
!Loader::IsBootableGameContainer(file, file_type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 program_id = 0;
|
||||
Loader::ResultStatus res = loader->ReadProgramId(program_id);
|
||||
if (res != Loader::ResultStatus::Success) {
|
||||
|
||||
@@ -49,12 +49,17 @@
|
||||
#include "common/settings.h"
|
||||
#include "common/string_util.h"
|
||||
#include "frontend_common/play_time_manager.h"
|
||||
#include "core/constants.h"
|
||||
#include "core/core.h"
|
||||
#include "core/cpu_manager.h"
|
||||
#include "core/crypto/key_manager.h"
|
||||
#include "core/file_sys/card_image.h"
|
||||
#include "core/file_sys/content_archive.h"
|
||||
#include "core/file_sys/control_metadata.h"
|
||||
#include "core/file_sys/fs_filesystem.h"
|
||||
#include "core/file_sys/romfs.h"
|
||||
#include "core/file_sys/nca_metadata.h"
|
||||
#include "core/file_sys/romfs.h"
|
||||
#include "core/file_sys/submission_package.h"
|
||||
#include "core/file_sys/vfs/vfs.h"
|
||||
#include "core/file_sys/vfs/vfs_real.h"
|
||||
@@ -84,6 +89,8 @@
|
||||
#include "jni/native.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
||||
#include "video_core/capture.h"
|
||||
#include "video_core/textures/decoders.h"
|
||||
#include "video_core/vulkan_common/vulkan_instance.h"
|
||||
#include "video_core/vulkan_common/vulkan_surface.h"
|
||||
#include "video_core/shader_notify.h"
|
||||
@@ -210,6 +217,10 @@ void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_manual_provider->AddEntriesFromContainer(file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto loader = Loader::GetLoader(m_system, file);
|
||||
if (!loader) {
|
||||
return;
|
||||
@@ -226,20 +237,16 @@ void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath)
|
||||
m_manual_provider->AddEntry(FileSys::TitleType::Application,
|
||||
FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()),
|
||||
program_id, file);
|
||||
} else if (res2 == Loader::ResultStatus::Success &&
|
||||
(file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
|
||||
const auto nsp = file_type == Loader::FileType::NSP
|
||||
? std::make_shared<FileSys::NSP>(file)
|
||||
: FileSys::XCI{file}.GetSecurePartitionNSP();
|
||||
for (const auto& title : nsp->GetNCAs()) {
|
||||
for (const auto& entry : title.second) {
|
||||
m_manual_provider->AddEntry(entry.first.first, entry.first.second, title.first,
|
||||
entry.second->GetBaseFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EmulationSession::ConfigureFilesystemProviderFromGameFolder(const std::string& filepath) {
|
||||
if (!Settings::values.ext_content_from_game_dirs.GetValue()) {
|
||||
return;
|
||||
}
|
||||
ConfigureFilesystemProvider(filepath);
|
||||
}
|
||||
|
||||
void EmulationSession::InitializeSystem(bool reload) {
|
||||
if (!reload) {
|
||||
// Initialize logging system
|
||||
@@ -683,9 +690,10 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_surfaceChanged(JNIEnv* env, jobject i
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_surfaceDestroyed(JNIEnv* env, jobject instance) {
|
||||
ANativeWindow_release(EmulationSession::GetInstance().NativeWindow());
|
||||
if (auto* native_window = EmulationSession::GetInstance().NativeWindow(); native_window) {
|
||||
ANativeWindow_release(native_window);
|
||||
}
|
||||
EmulationSession::GetInstance().SetNativeWindow(nullptr);
|
||||
EmulationSession::GetInstance().SurfaceChanged();
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setAppDirectory(JNIEnv* env, jobject instance,
|
||||
@@ -872,6 +880,40 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isPaused(JNIEnv* env, jclass claz
|
||||
return static_cast<jboolean>(EmulationSession::GetInstance().IsPaused());
|
||||
}
|
||||
|
||||
jbyteArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletCaptureBuffer(JNIEnv* env, jclass clazz) {
|
||||
using namespace VideoCore::Capture;
|
||||
|
||||
if (!EmulationSession::GetInstance().IsRunning()) {
|
||||
return env->NewByteArray(0);
|
||||
}
|
||||
|
||||
const auto tiled = EmulationSession::GetInstance().System().GPU().GetAppletCaptureBuffer();
|
||||
if (tiled.size() < TiledSize) {
|
||||
return env->NewByteArray(0);
|
||||
}
|
||||
|
||||
std::vector<u8> linear(LinearWidth * LinearHeight * BytesPerPixel);
|
||||
Tegra::Texture::UnswizzleTexture(linear, tiled, BytesPerPixel, LinearWidth, LinearHeight,
|
||||
LinearDepth, BlockHeight, BlockDepth);
|
||||
|
||||
auto buffer = env->NewByteArray(static_cast<jsize>(linear.size()));
|
||||
if (!buffer) {
|
||||
return env->NewByteArray(0);
|
||||
}
|
||||
|
||||
env->SetByteArrayRegion(buffer, 0, static_cast<jsize>(linear.size()),
|
||||
reinterpret_cast<const jbyte*>(linear.data()));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletCaptureWidth(JNIEnv* env, jclass clazz) {
|
||||
return static_cast<jint>(VideoCore::Capture::LinearWidth);
|
||||
}
|
||||
|
||||
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletCaptureHeight(JNIEnv* env, jclass clazz) {
|
||||
return static_cast<jint>(VideoCore::Capture::LinearHeight);
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass clazz,
|
||||
jboolean reload) {
|
||||
// Initialize the emulated system.
|
||||
@@ -1136,6 +1178,39 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_getDebugKnobAt(JNIEnv* env, jobje
|
||||
return static_cast<jboolean>(Settings::getDebugKnobAt(static_cast<u8>(index)));
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setTurboSpeedLimit(JNIEnv *env, jobject jobj, jboolean enabled) {
|
||||
if (enabled) {
|
||||
Settings::values.use_speed_limit.SetValue(true);
|
||||
Settings::SetSpeedMode(Settings::SpeedMode::Turbo);
|
||||
} else {
|
||||
Settings::SetSpeedMode(Settings::SpeedMode::Standard);
|
||||
}
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setSlowSpeedLimit(JNIEnv *env, jobject jobj, jboolean enabled) {
|
||||
if (enabled) {
|
||||
Settings::values.use_speed_limit.SetValue(true);
|
||||
Settings::SetSpeedMode(Settings::SpeedMode::Slow);
|
||||
} else {
|
||||
Settings::SetSpeedMode(Settings::SpeedMode::Standard);
|
||||
}
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_setStandardSpeedLimit(JNIEnv *env, jobject jobj, jboolean enabled) {
|
||||
Settings::values.use_speed_limit.SetValue(enabled);
|
||||
if (enabled) {
|
||||
Settings::SetSpeedMode(Settings::SpeedMode::Standard);
|
||||
}
|
||||
}
|
||||
|
||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isTurboMode(JNIEnv *env, jobject jobj) {
|
||||
return Settings::values.current_speed_mode.GetValue() == Settings::SpeedMode::Turbo;
|
||||
}
|
||||
|
||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isSlowMode(JNIEnv *env, jobject jobj) {
|
||||
return Settings::values.current_speed_mode.GetValue() == Settings::SpeedMode::Slow;
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run(JNIEnv* env, jobject jobj, jstring j_path,
|
||||
jint j_program_index,
|
||||
jboolean j_frontend_initiated) {
|
||||
@@ -1331,7 +1406,8 @@ jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env
|
||||
Common::Android::ToJString(env, patch.name),
|
||||
Common::Android::ToJString(env, patch.version), static_cast<jint>(patch.type),
|
||||
Common::Android::ToJString(env, std::to_string(patch.program_id)),
|
||||
Common::Android::ToJString(env, std::to_string(patch.title_id)));
|
||||
Common::Android::ToJString(env, std::to_string(patch.title_id)),
|
||||
static_cast<jlong>(patch.numeric_version));
|
||||
env->SetObjectArrayElement(jpatchArray, i, jpatch);
|
||||
++i;
|
||||
}
|
||||
@@ -1441,6 +1517,12 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_addFileToFilesystemProvider(JNIEnv* e
|
||||
Common::Android::GetJString(env, jpath));
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_addGameFolderFileToFilesystemProvider(
|
||||
JNIEnv* env, jobject jobj, jstring jpath) {
|
||||
EmulationSession::GetInstance().ConfigureFilesystemProviderFromGameFolder(
|
||||
Common::Android::GetJString(env, jpath));
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_clearFilesystemProvider(JNIEnv* env, jobject jobj) {
|
||||
EmulationSession::GetInstance().GetContentProvider()->ClearAllEntries();
|
||||
}
|
||||
@@ -1615,22 +1697,14 @@ JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_isNightlyBuild(
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_UPDATE_CHECKER
|
||||
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_checkForUpdate(
|
||||
JNIEnv* env,
|
||||
jobject obj) {
|
||||
const bool is_prerelease = ((strstr(Common::g_build_version, "pre-alpha") != nullptr) ||
|
||||
(strstr(Common::g_build_version, "alpha") != nullptr) ||
|
||||
(strstr(Common::g_build_version, "beta") != nullptr) ||
|
||||
(strstr(Common::g_build_version, "rc") != nullptr));
|
||||
const std::optional<UpdateChecker::Update> release =
|
||||
UpdateChecker::GetLatestRelease(is_prerelease);
|
||||
|
||||
if (!release || release->tag == Common::g_build_version) {
|
||||
return nullptr;
|
||||
}
|
||||
std::optional<UpdateChecker::Update> release = UpdateChecker::GetUpdate();
|
||||
if (!release) return nullptr;
|
||||
|
||||
const std::string tag = release->tag;
|
||||
const std::string name = release->name;
|
||||
@@ -1686,7 +1760,7 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
|
||||
#endif
|
||||
}
|
||||
|
||||
const std::string apk_filename = fmt::format("Eden-Android-{}-{}.apk", version_str, variant);
|
||||
const std::string apk_filename = fmt::format("Eden-Android-{}-{}.apk", artifact_str, variant);
|
||||
const std::string url = fmt::format("{}/{}/releases/download/{}/{}",
|
||||
std::string{Common::g_build_auto_update_website},
|
||||
std::string{Common::g_build_auto_update_repo},
|
||||
@@ -1694,6 +1768,7 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
|
||||
apk_filename);
|
||||
|
||||
env->ReleaseStringUTFChars(tag, version_str);
|
||||
env->ReleaseStringUTFChars(artifact, artifact_str);
|
||||
env->ReleaseStringUTFChars(packageId, package_id_str);
|
||||
return env->NewStringUTF(url.c_str());
|
||||
}
|
||||
@@ -1705,4 +1780,388 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getBuildVersion(
|
||||
return env->NewStringUTF(Common::g_build_version);
|
||||
}
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getAllUsers(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
|
||||
manager.ResetUserSaveFile();
|
||||
|
||||
if (manager.GetUserCount() == 0) {
|
||||
manager.CreateNewUser(Common::UUID::MakeRandom(), "Eden");
|
||||
manager.WriteUserSaveFile();
|
||||
}
|
||||
|
||||
const auto& users = manager.GetAllUsers();
|
||||
|
||||
jclass string_class = env->FindClass("java/lang/String");
|
||||
if (!string_class) {
|
||||
return env->NewObjectArray(0, env->FindClass("java/lang/Object"), nullptr);
|
||||
}
|
||||
|
||||
jsize valid_count = 0;
|
||||
for (const auto& user : users) {
|
||||
if (user.IsValid()) {
|
||||
valid_count++;
|
||||
}
|
||||
}
|
||||
|
||||
jobjectArray result = env->NewObjectArray(valid_count, string_class, nullptr);
|
||||
if (!result) {
|
||||
return env->NewObjectArray(0, string_class, nullptr);
|
||||
}
|
||||
|
||||
// fill array sequentially with only valid users
|
||||
jsize array_index = 0;
|
||||
for (const auto& user : users) {
|
||||
if (user.IsValid()) {
|
||||
jstring uuid_str = env->NewStringUTF(user.FormattedString().c_str());
|
||||
if (uuid_str) {
|
||||
env->SetObjectArrayElement(result, array_index++, uuid_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUserUsername(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jstring juuid) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
const auto uuid_string = Common::Android::GetJString(env, juuid);
|
||||
const auto uuid = Common::UUID{uuid_string};
|
||||
|
||||
Service::Account::ProfileBase profile{};
|
||||
if (!manager.GetProfileBase(uuid, profile)) {
|
||||
jstring result = env->NewStringUTF("");
|
||||
return result ? result : env->NewStringUTF("");
|
||||
}
|
||||
|
||||
const auto text = Common::StringFromFixedZeroTerminatedBuffer(
|
||||
reinterpret_cast<const char*>(profile.username.data()), profile.username.size());
|
||||
jstring result = env->NewStringUTF(text.c_str());
|
||||
return result ? result : env->NewStringUTF("");
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUserCount(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
return static_cast<jlong>(manager.GetUserCount());
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_canCreateUser(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
return manager.CanSystemRegisterUser();
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_createUser(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jstring juuid,
|
||||
jstring jusername) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
const auto uuid_string = Common::Android::GetJString(env, juuid);
|
||||
const auto username = Common::Android::GetJString(env, jusername);
|
||||
const auto uuid = Common::UUID{uuid_string};
|
||||
|
||||
const auto result = manager.CreateNewUser(uuid, username);
|
||||
if (result.IsSuccess()) {
|
||||
manager.WriteUserSaveFile();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_updateUserUsername(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jstring juuid,
|
||||
jstring jusername) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
const auto uuid_string = Common::Android::GetJString(env, juuid);
|
||||
const auto username = Common::Android::GetJString(env, jusername);
|
||||
const auto uuid = Common::UUID{uuid_string};
|
||||
|
||||
Service::Account::ProfileBase profile{};
|
||||
if (!manager.GetProfileBase(uuid, profile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::fill(profile.username.begin(), profile.username.end(), '\0');
|
||||
std::copy(username.begin(), username.end(), profile.username.begin());
|
||||
|
||||
if (manager.SetProfileBase(uuid, profile)) {
|
||||
manager.WriteUserSaveFile();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_removeUser(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jstring juuid) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
const auto uuid_string = Common::Android::GetJString(env, juuid);
|
||||
const auto uuid = Common::UUID{uuid_string};
|
||||
|
||||
const auto user_index = manager.GetUserIndex(uuid);
|
||||
if (!user_index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Settings::values.current_user.GetValue() == static_cast<s32>(*user_index)) {
|
||||
Settings::values.current_user = 0;
|
||||
}
|
||||
|
||||
if (manager.RemoveUser(uuid)) {
|
||||
manager.WriteUserSaveFile();
|
||||
manager.ResetUserSaveFile();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getCurrentUser(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
const auto user_id = manager.GetUser(Settings::values.current_user.GetValue());
|
||||
if (!user_id) {
|
||||
jstring result = env->NewStringUTF("");
|
||||
return result ? result : env->NewStringUTF("");
|
||||
}
|
||||
jstring result = env->NewStringUTF(user_id->FormattedString().c_str());
|
||||
return result ? result : env->NewStringUTF("");
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_setCurrentUser(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jstring juuid) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
const auto uuid_string = Common::Android::GetJString(env, juuid);
|
||||
const auto uuid = Common::UUID{uuid_string};
|
||||
|
||||
const auto index = manager.GetUserIndex(uuid);
|
||||
if (index) {
|
||||
Settings::values.current_user = static_cast<s32>(*index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUserImagePath(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jstring juuid) {
|
||||
const auto uuid_string = Common::Android::GetJString(env, juuid);
|
||||
const auto uuid = Common::UUID{uuid_string};
|
||||
|
||||
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) /
|
||||
fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormattedString());
|
||||
|
||||
jstring result = Common::Android::ToJString(env, Common::FS::PathToUTF8String(path));
|
||||
return result ? result : env->NewStringUTF("");
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_saveUserImage(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jstring juuid,
|
||||
jstring jimagePath) {
|
||||
const auto uuid_string = Common::Android::GetJString(env, juuid);
|
||||
const auto uuid = Common::UUID{uuid_string};
|
||||
const auto image_source = Common::Android::GetJString(env, jimagePath);
|
||||
|
||||
const auto dest_path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) /
|
||||
fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormattedString());
|
||||
|
||||
const auto dest_dir = dest_path.parent_path();
|
||||
if (!Common::FS::CreateDirs(dest_dir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
std::filesystem::copy_file(image_source, dest_path,
|
||||
std::filesystem::copy_options::overwrite_existing);
|
||||
return true;
|
||||
} catch (const std::filesystem::filesystem_error& e) {
|
||||
LOG_ERROR(Common_Filesystem, "Failed to copy image file: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadProfiles(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
auto& manager = EmulationSession::GetInstance().System().GetProfileManager();
|
||||
manager.ResetUserSaveFile();
|
||||
|
||||
// create a default user if non exist
|
||||
if (manager.GetUserCount() == 0) {
|
||||
manager.CreateNewUser(Common::UUID::MakeRandom(), "Eden");
|
||||
manager.WriteUserSaveFile();
|
||||
}
|
||||
|
||||
LOG_INFO(Service_ACC, "Profile manager reloaded, user count: {}", manager.GetUserCount());
|
||||
}
|
||||
|
||||
// for firmware avatar images
|
||||
static std::vector<uint8_t> DecompressYaz0(const FileSys::VirtualFile& file) {
|
||||
if (!file) {
|
||||
return std::vector<uint8_t>();
|
||||
}
|
||||
|
||||
uint32_t magic{};
|
||||
file->ReadObject(&magic, 0);
|
||||
if (magic != Common::MakeMagic('Y', 'a', 'z', '0')) {
|
||||
return std::vector<uint8_t>();
|
||||
}
|
||||
|
||||
uint32_t decoded_length{};
|
||||
file->ReadObject(&decoded_length, 4);
|
||||
decoded_length = Common::swap32(decoded_length);
|
||||
|
||||
std::size_t input_size = file->GetSize() - 16;
|
||||
std::vector<uint8_t> input(input_size);
|
||||
file->ReadBytes(input.data(), input_size, 16);
|
||||
|
||||
uint32_t input_offset{};
|
||||
uint32_t output_offset{};
|
||||
std::vector<uint8_t> output(decoded_length);
|
||||
|
||||
uint16_t mask{};
|
||||
uint8_t header{};
|
||||
|
||||
while (output_offset < decoded_length) {
|
||||
if ((mask >>= 1) == 0) {
|
||||
if (input_offset >= input.size()) break;
|
||||
header = input[input_offset++];
|
||||
mask = 0x80;
|
||||
}
|
||||
|
||||
if ((header & mask) != 0) {
|
||||
if (output_offset >= output.size() || input_offset >= input.size()) {
|
||||
break;
|
||||
}
|
||||
output[output_offset++] = input[input_offset++];
|
||||
} else {
|
||||
if (input_offset + 1 >= input.size()) break;
|
||||
uint8_t byte1 = input[input_offset++];
|
||||
uint8_t byte2 = input[input_offset++];
|
||||
|
||||
uint32_t dist = ((byte1 & 0xF) << 8) | byte2;
|
||||
uint32_t position = output_offset - (dist + 1);
|
||||
|
||||
uint32_t length = byte1 >> 4;
|
||||
if (length == 0) {
|
||||
if (input_offset >= input.size()) break;
|
||||
length = static_cast<uint32_t>(input[input_offset++]) + 0x12;
|
||||
} else {
|
||||
length += 2;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < length && output_offset < decoded_length; ++i) {
|
||||
output[output_offset++] = output[position++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static FileSys::VirtualDir GetFirmwareAvatarDirectory() {
|
||||
constexpr u64 AvatarImageDataId = 0x010000000000080AULL;
|
||||
|
||||
auto* bis_system = EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto nca = bis_system->GetEntry(AvatarImageDataId, FileSys::ContentRecordType::Data);
|
||||
if (!nca) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto romfs = nca->GetRomFS();
|
||||
if (!romfs) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto extracted = FileSys::ExtractRomFS(romfs);
|
||||
if (!extracted) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return extracted->GetSubdirectory("chara");
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getFirmwareAvatarCount(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
const auto chara_dir = GetFirmwareAvatarDirectory();
|
||||
if (!chara_dir) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (const auto& item : chara_dir->GetFiles()) {
|
||||
if (item->GetExtension() == "szs") {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getFirmwareAvatarImage(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj,
|
||||
jint index) {
|
||||
const auto chara_dir = GetFirmwareAvatarDirectory();
|
||||
if (!chara_dir) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int current_index = 0;
|
||||
for (const auto& item : chara_dir->GetFiles()) {
|
||||
if (item->GetExtension() != "szs") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current_index == index) {
|
||||
auto image_data = DecompressYaz0(item);
|
||||
if (image_data.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
jbyteArray result = env->NewByteArray(image_data.size());
|
||||
if (result) {
|
||||
env->SetByteArrayRegion(result, 0, image_data.size(),
|
||||
reinterpret_cast<const jbyte*>(image_data.data()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
current_index++;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getDefaultAccountBackupJpeg(
|
||||
JNIEnv* env,
|
||||
[[maybe_unused]] jobject obj) {
|
||||
jbyteArray result = env->NewByteArray(Core::Constants::ACCOUNT_BACKUP_JPEG.size());
|
||||
if (result) {
|
||||
env->SetByteArrayRegion(result, 0, Core::Constants::ACCOUNT_BACKUP_JPEG.size(),
|
||||
reinterpret_cast<const jbyte*>(Core::Constants::ACCOUNT_BACKUP_JPEG.data()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -46,6 +49,7 @@ public:
|
||||
const Core::PerfStatsResults& PerfStats();
|
||||
int ShadersBuilding();
|
||||
void ConfigureFilesystemProvider(const std::string& filepath);
|
||||
void ConfigureFilesystemProviderFromGameFolder(const std::string& filepath);
|
||||
void InitializeSystem(bool reload);
|
||||
void SetAppletId(int applet_id);
|
||||
Core::SystemResultStatus InitializeEmulation(const std::string& filepath,
|
||||
|
||||