From 44fa2805d6c6d2b1a7e838d27d7d6eafb9c57420 Mon Sep 17 00:00:00 2001 From: rayman30 Date: Sun, 3 May 2026 04:29:49 +0200 Subject: [PATCH 01/58] [macos, dynarmic] Implement VectorMin/Max{S,U}64 emitters (Apple Silicon fix) (#3421) [macos] dynarmic: Implement VectorMin/Max{S,U}64 emitters (Apple Silicon fix) Implements the missing A64 backend emitters for VectorMinS64, VectorMinU64, VectorMaxS64, and VectorMaxU64. These IR opcodes are generated by the optimizer but lack direct hardware instruction support for 64-bit elements in the base NEON set (e.g., UMIN.2D does not exist). They are implemented using a compare (CMGT/CMHI) followed by a bitwise select (BSL). This correctly selects between the two source registers, whereas using BIT would incorrectly zero out elements. This implementation is guarded by #ifdef __APPLE__ to ensure no impact on other platforms. Unit tests could not be added to a64.cpp because UMIN.2D is not a valid A64 instruction, causing the assembler (Oaknut) to reject it. The fix was verified by running Team Sonic Racing, which previously crashed on this synthetic opcode. Fixes crash in Team Sonic Racing on macOS. Co-authored-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3421 Reviewed-by: Lizzie Reviewed-by: crueter --- .../backend/arm64/emit_arm64_vector.cpp | 32 +++++++++---------- src/dynarmic/tests/A64/a64.cpp | 31 ++++++++++++++++-- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector.cpp index 6ac8531bfc..d575cd66ee 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64_vector.cpp @@ -866,10 +866,10 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - (void)code; - (void)ctx; - (void)inst; - UNREACHABLE(); + EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) { + code.CMGT(Qresult->D2(), Qa->D2(), Qb->D2()); + code.BSL(Qresult->B16(), Qa->B16(), Qb->B16()); + }); } template<> @@ -889,10 +889,10 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - (void)code; - (void)ctx; - (void)inst; - UNREACHABLE(); + EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) { + code.CMHI(Qresult->D2(), Qa->D2(), Qb->D2()); + code.BSL(Qresult->B16(), Qa->B16(), Qb->B16()); + }); } template<> @@ -912,10 +912,10 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - (void)code; - (void)ctx; - (void)inst; - UNREACHABLE(); + EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) { + code.CMGT(Qresult->D2(), Qb->D2(), Qa->D2()); + code.BSL(Qresult->B16(), Qa->B16(), Qb->B16()); + }); } template<> @@ -935,10 +935,10 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - (void)code; - (void)ctx; - (void)inst; - UNREACHABLE(); + EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) { + code.CMHI(Qresult->D2(), Qb->D2(), Qa->D2()); + code.BSL(Qresult->B16(), Qa->B16(), Qb->B16()); + }); } template<> diff --git a/src/dynarmic/tests/A64/a64.cpp b/src/dynarmic/tests/A64/a64.cpp index e85986ea5a..9bd9c36a86 100644 --- a/src/dynarmic/tests/A64/a64.cpp +++ b/src/dynarmic/tests/A64/a64.cpp @@ -1787,7 +1787,7 @@ TEST_CASE("A64: rand3", "[a64]") { A64::Jit jit{config}; memset(backing_memory, 0, memory_size); - // cat rand2.txt | awk '{print "env.code_mem.emplace_back(0x"$2"); // "$0}' > rand2-out.txt + // cat rand2.txt | awk '{print "env.code_mem.emplace_back(0x"$2"); // "$0}' > rand2-out.tx env.MemoryWrite32(100, 0x58028edd); // 0000000000000084 58028edd ldr x29, #20952 env.MemoryWrite32(104, 0x14000000); // 0000000000000ea4 14000000 b #0 @@ -1821,7 +1821,7 @@ TEST_CASE("A64: rand2", "[a64][.]") { A64::Jit jit{config}; memset(backing_memory, 0, memory_size); - // cat rand2.txt | awk '{print "env.code_mem.emplace_back(0x"$2"); // "$0}' > rand2-out.txt + // cat rand2.txt | awk '{print "env.code_mem.emplace_back(0x"$2"); // "$0}' > rand2-out.tx const std::array code32 = {0xea80f352, 0x6e65e59d, 0x1e20c343, 0x2e3a7192, 0x2e267249, 0xd500405f, 0x6f01f461, 0x6eb684fc, 0x58028edd, 0x0ea5f5b6, 0x0ea069fb, 0x2e769517, 0x5e066063, 0x1e65c3f5, 0x4f00ff52, 0x93401cf6, 0x1e274248, 0x6f67aaf5, 0x5e0c0782, 0x5ef43f3c, 0x2e6595b7, 0x4e20590f, 0xb35aa451, 0x6ee2c5ed, 0x4e32bf46, 0x2ea1ba8f, 0x2f68a85e, 0x9237d90a, 0x5e23dd10, 0x0e762e32, 0x4e31a8cf, 0xce1f3360, 0x781a4ac0, 0x13834066, 0x5fa8101c, 0x6f7c5594, 0x0e71bb68, 0xbc0b3e8f, 0x785dbbda, 0x6f51e794, 0xce50af75, 0x1ad728ec, 0x6ee0da4c, 0xb84efa14, 0x2eb3f613, 0x4e287ade, 0x4eb8c734, 0x2e83f4e8, 0x0e397c80, 0xd08f93f8, 0xce718e48, 0x0f672a0d, 0x2e9edd40, 0x0e14128b, 0x6f5942e6, 0x8b3a0f03, 0x3c5d16b9, 0x7f7e3743, 0x4f4c54e4, 0x0ea0a9e9, 0x9e59dbe6, 0x6e7ddcd3, 0xcec08377, 0x9ba759f8, 0x2ea5046e, 0x0e24c569, 0xb8979780, 0x4e31b98c, 0x4efe4f46, 0x4ea7c762, 0x7e61c9c6, 0x6e30c880, 0x1ada0c25, 0x4e603a2f, 0xda9d7218, 0x0d40c5d9, 0x5e214b05, 0x9ba9efc5, 0x5e61b81e, 0x6e7bc31c, 0x0e61a163, 0x9e5832d2, 0x4e772248, 0x4e3d17c8, 0x92624f60, 0x7a1a02dc, 0x79891f65, 0x6eb45036, 0x0e321ee8, 0x4e2566f0, 0x4ea02b9b, 0x0f9dcb3d, 0x2e21b9f9, 0x0e21a8c3, 0xda1700bd, 0x6ea0fb38, 0x7e607a0b, 0x72845817, 0x7f61068e, 0x0d60e529, 0x4ea0ca5c, 0x1a94b20f, 0x8b87419d, 0x7ea9ed71, 0x2ea1a86e, 0x4d40c4da, 0x5ea0eada, 0x784ba96e, 0x7eb6ee02, 0x3db1c710, 0x0e217836, 0x7ee0bb96, 0x4e786c08, 0x4e976a08, 0x489ffe86, 0x4e79fc9b, 0x0e21cbce, 0x5ef7fc65, 0x4ea1286d, 0xd29c771e, 0x6f5c2839, 0x0ea00a9d, 0x6ee44c06, 0x5ee1d858, 0x5ef2fda6, 0x7eb0c9fe, 0x7f762791, 0x2e212ae6, 0x4e61c9db, 0x13003c57, 0x5ee1b8f8, 0x0f2396d2, 0x6ea0db1e, 0x0e71ba82, 0xab29c807, 0x6ef8f8b3, 0x1f18d4a1, 0x0e261d15, 0x1e290081, 0x1b0c7d12, 0x4e7771c3, 0xf845f1e4, 0x4d40c9e8, 0xce778452, 0x6eb9879d, 0x6e21c93d, 0xcec0829f, 0x52a0969f, 0x1e772b4f, 0x7ee1da88, 0x5f52fe0a, 0x7f3387b1, 0x5e214850, 0x1e65c025, 0x0e2ca294, 0x2e614829, 0x1e640077, 0x9e240048, 0x4ebe9537, 0x9bb7925e, 0x38b669c5, 0x2840d089, 0x6f43e648, 0x2e662d28, 0x4eabaff3, 0x6e734cc7, 0x0e31baee, 0x7ee0d93c, 0x5e282bde, 0x7e21bba4, 0x4e6c75fa, 0x5ac01217, 0x7f4304af, 0x1e7878ed, 0x1ada2196, 0x7ee1aba3, 0x93407f3c, 0x4f6c34eb, 0x6e3447a9, 0x7e7ae545, 0x5e0802bb, 0x6eeae63a, 0x7ee1da62, 0x5e280bb3, 0xf81d4009, 0x1e603b21, 0x5e281a14, 0x6eb0a99b, 0x1e266a25, 0x0d60cafe, 0x0e0b6194, 0x7a4ed2c5, 0x92b762ec, 0x4e6b5749, 0x3c16a6e5, 0x4ea0a92b, 0x0fa58b6a, 0x5f76148c, 0x6e30c95f, 0x1e6540fd, 0x5e28e40f, 0x0d403fd4, 0x7e30da36, 0x7fda9b51, 0x2ea04bde, 0x1e25c3d2, 0x1ee0434c, 0x5e21d8e7, 0x5ee1ba51, 0x5e61aba9, 0x4e2849fb, 0x5ee098ea, 0x4e60f63d, 0x0f280443, 0x5ee0da27, 0x2e78a6ce, 0x78054afc, 0x4e14286b, 0x4e218bd8, 0x2a3d2551, 0x3a04017a, 0x5f4317cd, 0x0e604a37, 0x9a834614, 0x0e2edf4d, 0x7a51a0a0, 0x5f8e9043, 0x6ea06bb2, 0xaa2857dd, 0x7a1903fc, 0x301ba9ba, 0x9ac929cd, 0x4e061ff0, 0x2e38fcfc, 0x0e2f614a, 0x7ee0d8e4, 0x6e73afda, 0x7f4156f7, 0x0e6078bf, 0x4ee1d9ed, 0x93403fbe, 0xce6f8640, 0x4e3855e3, 0x6f76fe23, 0x112466e8, 0x1e358a90, 0x7f45272c, 0x6ea19a9d, 0x8a696350, 0x1e3900f6, 0x5e61c866, 0x0e3fbfd0, 0x5ee09ad0, 0x0e651d27, 0x4dffc35e, 0x2e20c6ce, 0x0fbe118d, 0x1e656a15, 0xd1357365, 0x0e20a847, 0xce4a835c, 0x4e203905, 0x2e60090d, 0x7f4a27bb, 0x1e64c316, 0xce7d86a4, 0x7ebded2d, 0x6e70a97e, 0x4eb9a42b, 0x0e209bef, 0x6f151730, 0x0e7e30f7, 0x4e724509, 0xd503375f, 0xce58b6ae, 0x5e21a9b8, 0xcb2ca538, 0x5ac01131, 0x6ea19a24, 0xeb40c8b3, 0xc8df7d65, 0x78108341, 0x3218ab9b, 0x0f3da7dd, 0x2e003089, 0x4e21cab5, 0x8aa5c924, 0x1a94950c, 0x123e506f, 0x13117e37, 0x1ee6005b, 0x5ac00647, 0x5eec8cd5, 0x7ef0fb3d, 0x9223272a, 0x5ee0cb02, 0x6e66071d, 0x6ea1dbbf, 0x5e61c903, 0x5ac015ea, 0x93db6206, 0x7e62b5e3, 0x6ea0c87b, 0xdac0090e, 0x48df7d90, 0x6e206ba5, 0x9e2503c2, 0x6e25fc89, 0x4d60e2db, 0x1e3e22a0, 0x2eb81c19, 0x7856ea00, 0x5fbfb22d, 0x1e630244, 0x4e202a83, 0x1f50a722, 0x7f7b55d2, 0x0fae89b9, 0x4e781d73, 0xce738c3a, 0x4f15a591, 0x6e21c7e1, 0x586ff77e, 0x8a5d3592, 0x93401c67, 0x5e61cb86, 0xce6bc2c1, 0x6e393f10, 0x9bb70ec3, 0xdac0098c, 0x4da84b95, 0x7f494476, 0x9ace5c11, 0x7e61ca14, 0x4f7a60ef, 0x1ad32b39, 0x0ea3777f, 0x5e61da7f, 0x4f1404e2, 0x4e3244e2, 0x6e1b1ceb, 0x0dee5aac, 0x4e2f9dc4, 0x5ea1b8c3, 0x1e59f863, 0xd500403f, 0x4e3ae7d0, 0x4ef5c6ea, 0x08dffe3b, 0x6e36f4f6, 0x2e764f29, 0x0e726f23, 0x5f42375b, 0x7f71fc40, 0x6e618aad, 0x93403e5b, 0x0e205976, 0x0e7250c4, 0x6eb0abc9, 0x2e2049f0, 0x5f14754d, 0x7f6ce468, 0x6f950bbe, 0x6e31aa47, 0x4eb83396, 0x0dccc952, 0x2ea1ca90, 0xce69c701, 0xb0bed69e, 0x7c5dec39, 0x4e2868a2, 0x0e591b08, 0x5f34e6dd, 0x3a449184, 0x5e3ce6de, 0x4ea149b7, 0x4e7ad29b, 0xba198503, 0x1f683e8f, 0xfa52f2a7, 0x6e30dffc, 0x4e6c3d17, 0x2eae3248, 0xd503349f, 0x1e60002c, 0x0f180680, 0x9e240049, 0x6f75774e, 0xa90d8678, 0x9ad924c4, 0x7eb0f85b, 0x0e205aaf, 0x7ee08899, 0x5f4bffd8, 0x1b0ff5f3, 0x4ee11dcd, 0x2e218948, 0x0dcb2733, 0x4eac107c, 0x4ea04a53, 0x4e287b44, 0x0e60b82a, 0x5ee0ebbc, 0xce454ff1, 0x5e1761e7, 0x5e09202f, 0x0e0c0754, 0x1e72e6b9, 0x7e21da70, 0x0fbdb20c, 0x5efb8c84, 0xd500401f, 0x3a47526e, 0x1e680acf, 0x7f7375fc, 0xf80522da, 0x4ee60c02, 0x4d40c2e7, 0x6f89096b, 0x7ee1bb6e, 0x5e280b4a, 0x1e3120c8, 0x7eb2ef96, 0x4fd012dd, 0x0f3027ef, 0x4e2078a8, 0xd503201f, 0x2e2312d9, 0x6ebf1c6e, 0x5ee1f8df, 0x4e607a46, 0x6e30c877, 0x6c09d2d1, 0x4e61abd8, 0x0e35267e, 0x6ac17728, 0x0e861aa0, 0x6f63fe26, 0x6f157628, 0x6f30a5f9, 0x4d60cc0c, 0x4e21cb59, 0x2e68a3fb, 0x7efae601, 0x6ea0f82c, 0x9b25ec12, 0x1a1a0305, 0x0e043fe1, 0x6e73c0ed, 0x6ea1b8c0, 0x7e20380b, 0x0f0534e8, 0x1f56bc7d, 0xba0c0128, 0x1e672160, 0x6e7b259b, 0x7ee07b5d, 0x9a820443, 0x4e040581, 0x2f1d87e8, 0x1acd2f5b, 0x6e20794f, 0x2e6a3c93, 0xc8dffe13, 0xce5ab1c6, 0x6eea55f6, 0x4ea039b3, 0x0d602fec, 0x2e246e2f, 0x7857be39, 0xb80608fb, 0x1e67c017, 0x9bcf7f63, 0x0f92d857, 0x5e0812f7, 0x1e210172, 0x7e6128e9, 0x7ea94d41, 0x981179e1, 0x1effb018, 0x2e600828, 0x0eb9c6b2, 0x6ee1baae, 0x4ea0db28, 0x2ea1487b, 0x4ea6c7f0, 0x2e2374c7, 0x7e30d8dd, 0xb9991fa7, 0x4e791e3e, 0x889f7c4b, 0x0e6c753c, 0x1e740ad1, 0x1e244324, 0x1ef33010, 0x5ac01102, 0x9bd97fba, 0x6e290143, 0x1e2220d8, 0x4d8d5aee, 0x6f28570b, 0xfa4ab0c1, 0xdac00b14, 0x7ea1a90e, 0x2e3027d8, 0x6f25a733, 0x4e61a96e, 0x4e1a2fcb, 0x0e22fe0a, 0xc8df7cd0, 0x5e280a55, 0x4e012b20, 0x7e70dbf4, 0x520c5a4e, 0x6ea6c57f, 0x0e861af8, 0xd503233f, 0x889ffe3c, 0x5e274ea9, 0x4e21a89a, 0x0e170c02, 0x6efd4c0b, 0xd5033ebf, 0x6e61a92c, 0x2e205b72, 0x789fb828, 0x0e626e94, 0x2ea6724c, 0x9a10028b, 0x2c6c51fc, 0x5a9de6b9, 0x6e6881f3, 0x5ee0ea6b, 0x0faec36e, 0x0e955bca, 0x1acf206d, 0x7f6f571b, 0x4e286930, 0x12b41ceb, 0x1e770b7a, 0x0ea18ac2, 0x5e282aaf, 0xf2b7fa1e, 0x1ac34311, 0x13167d11, 0x4ea63412, 0x6e758038, 0x2f1d85d6, 0x0f275480, 0x0ead6c71, 0x6e204b69, 0x1e6303f4, 0x5e0031ef, 0x13001e40, 0x7a16006f, 0x6e6ae4c0, 0x0f0f242f, 0x6e674f50, 0x4e606b7a, 0x7e6ee684, 0x1e6b5957, 0x7ea1bbab, 0x7ea0b6cb, 0xce4da241, 0x0ea1b953, 0x0eb2af4b, 0x9ac309d0, 0x6e61d8bd, 0x5ea0d890, 0x5f47d1e7, 0xfa5981ca, 0x1e7f7959, 0x6ef24dd8, 0x0e0a41d1, 0x5ee0e898, 0x4e6038e2, 0x13097d65, 0x6f839088, 0x9e290265, 0x0e208824, 0x2e65af79, 0x6f36a561, 0x9ad3204b, 0x0e21482e, 0x1e24431d, 0xd50330bf, 0x0df641aa, 0x6e602a83, 0xce30505f, 0x5e025238, 0xd503201f, 0x4e608880, 0x4de9c38d, 0x5e0f5348, 0x6eb48ca9, 0x50fda31b, 0x2e251eec, 0x7842ba50, 0xd8a1cd86, 0x2ea09862, 0x0ea09983, 0x2ea333b0, 0x0ea6032c, 0x4f94801b, 0x7e3ee57d, 0x38135e4f, 0xd8fdd9dd, 0x5ee0fcde, 0x9e64033d, 0x6e37f547, 0x6e3dd7ef, 0x13003f3d, 0x0e602f9f, 0x4e7ad014, 0x9b3b6857, 0x5ea0cb67, 0x0eb31c9f, 0x4e7c5372, 0x5e61b8c0, 0x0ea19b23, 0x0ee6e1df, 0x6e63a626, 0x2f139405, 0x7eb0f96d, 0x9e588c63, 0x2e714c3a, 0x6e8c941e, 0x0f61b331, 0x6f01f625, 0x4e78d4ea, 0x6f403709, 0x1a0300da, 0xda0102c8, 0x7e61d9fd, 0xb89469bb, 0x0c838780, 0x2e60a590, 0x4dfd29e1, 0x4e150f2e, 0xce2810bc, 0x5f541591, 0x9ee60259, 0x2eb40e56, 0x5e014027, 0x2ef71faf, 0x4e2d452f, 0x5ee0a813, 0x4eb03301, 0x38443acf, 0x6eabd502, 0x0e2ee71e, 0x5a960364, 0xce7ec596, 0x7efbed09, 0x4ef42ea2, 0x0eb30ea5, 0x5ee0d9f8, 0x6f513552, 0xf89eb3fa, 0x7ea2eca6, 0x9b00cc19, 0xf897409e, 0x1e73485f, 0x381afa77, 0x0f169f3b, 0x5ee1aa70, 0x5e1803ee, 0x0dbf5a4c, 0xce78c7a6, 0x9b0b260c, 0x2ef8fa19, 0x6e70aa4b, 0xce45b805, 0x2ea08e86, 0x4ee0bafd, 0x2ea09a1f, 0x4e218900, 0x6e744f13, 0xce518653, 0xf81b7a68, 0xce45ac5e, 0x7e62e416, 0x1a1b02b6, 0x7e21db48, 0x381daaaf, 0x6b2c0987, 0x0e2ec651, 0x4eae8502, 0x9bde7ca0, 0x6f47201f, 0x7e61a8a3, 0x6e60d5db, 0x4e2879de, 0xf81d194e, 0x4f1b8d05, 0x4d0048b2, 0x6e203be9, 0x4e3e7eb1, 0x0e260ef8, 0x2e688518, 0x7e3fec46, 0xdac00843, 0xf85c8917, 0x2e212a0f, 0x0e8196da, 0xd503359f, 0xce4c81f2, 0x6ee19992, 0x6e21ca79, 0x4d40c1d2, 0x4f5816ef, 0x4e34c3ea, 0x4df7c283, 0x7ef7eeb6, 0x18e276ce, 0xab0d21c0, 0xd5032f7f, 0x4ea00dbf, 0x5ac01251, 0xd0121955, 0x7f1495e4, 0x7ef0fa11, 0x5e24dd9c, 0x9add25b5, 0x0eb2bdef, 0x9e1977c7, 0x6f4b26bd, 0x0e200a9c, 0x9b4f7c00, 0x0ea0392e, 0x7e212a2c, 0x0b248b90, 0x1acc27a1, 0x2e701c90, 0x5ee1b870, 0x5e280aba, 0x5ea0780e, 0x1e264246, 0x4e052d04, 0x0e731dc4, 0xce461997, 0x9a9e9413, 0x3d462048, 0x5ea1fac5, 0x2ea0c8c4, 0x9a030280, 0x2ebda4b8, 0x5eef8614, 0x6eadc4e0, 0xbd035a8f, 0x4e606b84, 0x4eb1aba1, 0x4e286928, 0x4e2858cc, 0x9add0ce9, 0x4e070d65, 0x5fd399d5, 0x0f03fde7, 0x6ee90c74, 0x4ef8e31e, 0x381d986a, 0x5ea0ebf4, 0x5ea0d87e, 0x2e76ac9e, 0x6eb36cd4, 0x2e6e1c4c, 0x2e2feebc, 0x1ace4b03, 0x5ee0db12, 0x5ea0e9b1, 0x2e1c32d5, 0x5fa49a09, 0x0e258737, 0x7e21ca8e, 0xce4f9988, 0x5f7f56a6, 0x0e739766, 0x4e28586c, 0x6e619908, 0xd500401f, 0xf88b9252, 0x6e251c8e, 0x9e20015b, 0x7f1486b9, 0x717c339b, 0x1f31ff70, 0x4ea0eb62, 0x9acb0926, 0x489f7d85, 0x4e209b54, 0x2e84cf03, 0x2e65946c, 0x0e7d80cd, 0xc8dffecc, 0xce668bd8, 0x6e2188af, 0xeb4ada34, 0x2b25ec33, 0x0d40e6e7, 0x4eb2c757, 0x4ec82ad0, 0x7e21cb0a, 0x0e21a847, 0x4e0b1ec0, 0x381e6ac0, 0x6e61c8f5, 0x0f10071c, 0x2ee21daa, 0x5e61ab31, 0x6e218892, 0x2e7e7cb5, 0x6f2826aa, 0x7f6b54df, 0x4eaa2620, 0xdac00034, 0x4f6477be, 0x7e6148ea, 0x4eef1f57, 0x78459aeb, 0x2ebc3f10, 0x2e35f4eb, 0x4fbf19ce, 0xd8d0e58e, 0x2e21bbc7, 0x6ee0cab6, 0x9bc57e3f, 0x2f854037, 0x4e92181c, 0x6e6d1f89, 0x0f305545, 0x4ee19a57, 0x0e887bdf, 0x5e1a4185, 0x7ef0c821, 0x2eb6607c, 0x2ea0d9b8, 0x9e0380f4, 0x2ebf1c83, 0x1e62597d, 0x7f6e2548, 0x5ac00205, 0x4e616adb, 0xce638b8c, 0x5e1653cf, 0x2e6069be, 0x0e2ac641, 0x1e33c76f, 0xce44956d, 0x9bb90d31, 0x1e24c20a, 0x7ee038c1, 0x93407e5e, 0x4e280127, 0xc8df7f7d, 0xba42f263, 0x1e6f199c, 0x6e212889, 0x6e92f60e, 0x6ebdc499, 0x8b9acbf8, 0x4d40c581, 0x3a020250, 0x6e6a6716, 0x9248403b, 0x9081ffea, 0x4e603856, 0x9ad1242b, 0x6f270579, 0x1a070349, 0xcec08133, 0xd503305f, 0x5a1a00ca, 0x2e60b8a2, 0x0e5f28fd, 0x0e31a3da, 0x7e61cbc1, 0xd503399f, 0x5f5e54aa, 0x0eb8bdea, 0x4eba8f10, 0x4e2a2e60, 0x2f3da7d6, 0x1e58e297, 0x6e71aa3e, 0x6b86701a, 0xce4fa5e6, 0x4ee7c463, 0x8a79307f, 0x0ebea541, 0x2e218af4, 0x4e774f8a, 0xb9b95dc5, 0x6e61abd5, 0x4dd1e814, 0x4da72098, 0x98307582, 0x3a512101, 0x7ef95497, 0x1ace5535, 0x5a0c0349, 0x4e28581b, 0x6ebf1c02, 0x5ea1da23, 0x1e274314, 0x5e25dd29, 0x6e75f594, 0x6eaf6ed5, 0x4e214abe, 0x4e064172, 0x2e21c8f4, 0xf84c5b08, 0x1e244312, 0x14000000}; for (size_t i = 0; i < code32.size(); ++i) env.MemoryWrite32(100 + i, code32[i]); @@ -2576,3 +2576,30 @@ TEST_CASE("A64: CLZ{W}", "[a64]") { REQUIRE(jit.GetRegister(1) == 4); REQUIRE(jit.GetRegister(2) == 5); } + +TEST_CASE("A64: Manual Vector Min/Max U64 (Optimizer Test)", "[a64]") { + A64TestEnv env; + A64::UserConfig jit_user_config{}; + jit_user_config.callbacks = &env; + A64::Jit jit{jit_user_config}; + + oaknut::VectorCodeGenerator code{env.code_mem, nullptr}; + + // MaxU64 pattern: (a > b) ? a : b + code.CMHI(V2.D2(), V0.D2(), V1.D2()); // V2 = Mask (A > B) + code.BSL(V2.B16(), V0.B16(), V1.B16()); // V2 = Resul + + // MinU64 pattern: (a > b) ? b : a + code.CMHI(V3.D2(), V0.D2(), V1.D2()); // V3 = Mask (A > B) + code.BSL(V3.B16(), V1.B16(), V0.B16()); // V3 = Resul + + jit.SetPC(0); + jit.SetVector(0, {100, 20}); + jit.SetVector(1, {50, 200}); + + env.ticks_left = env.code_mem.size(); + CheckedRun([&]() { jit.Run(); }); + + CHECK(jit.GetVector(2) == Vector{100, 200}); + CHECK(jit.GetVector(3) == Vector{50, 20}); +} From a76c76d122129da7399cd9b6a5d9d6695a95e8cf Mon Sep 17 00:00:00 2001 From: ryana Date: Mon, 4 May 2026 18:15:55 +0200 Subject: [PATCH 02/58] [shader_recompiler] handle dynamic texture descriptor strides (#3898) this fixes dynamic texture descriptors that are not laid out as simple 8-byte entries tested on steam deck/amd notes - DynamicDescriptorSizeShift called twice because i moved it away from the struct but doing it this way keeps the patch just in this single file than adding a new derived field in the shared struct (i also think its just a cheap recomputation anyways) - removed cbuf scanning because i figured out how to do a bounds check statically credits: - Mythrax (identified the 1024 descriptor cap fix in #3897) Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3898 Reviewed-by: crueter --- src/shader_recompiler/host_translate_info.h | 6 + src/shader_recompiler/ir_opt/texture_pass.cpp | 129 ++++++++++++++++-- .../renderer_vulkan/vk_compute_pipeline.cpp | 5 +- .../renderer_vulkan/vk_pipeline_cache.cpp | 3 + src/video_core/vulkan_common/vulkan_device.h | 12 ++ 5 files changed, 140 insertions(+), 15 deletions(-) diff --git a/src/shader_recompiler/host_translate_info.h b/src/shader_recompiler/host_translate_info.h index 1b53404fcc..4a9261d5f5 100644 --- a/src/shader_recompiler/host_translate_info.h +++ b/src/shader_recompiler/host_translate_info.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -17,6 +20,9 @@ struct HostTranslateInfo { bool support_snorm_render_buffer{}; ///< True when the device supports SNORM render buffers bool support_viewport_index_layer{}; ///< True when the device supports gl_Layer in VS u32 min_ssbo_alignment{}; ///< Minimum alignment supported by the device for SSBOs + u32 max_per_stage_descriptor_sampled_images{1024}; ///< maximum sampled descriptors per stage + u32 max_per_stage_resources{4096}; ///< maximum resources per stage + u32 max_descriptor_set_sampled_images{1024}; ///< maximum sampled descriptors per set bool support_geometry_shader_passthrough{}; ///< True when the device supports geometry ///< passthrough shaders bool support_conditional_barrier{}; ///< True when the device supports barriers in conditional diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index 20b8591072..55b6f7213c 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp @@ -32,6 +32,71 @@ using TextureInstVector = boost::container::small_vector; constexpr u32 DESCRIPTOR_SIZE = 8; constexpr u32 DESCRIPTOR_SIZE_SHIFT = static_cast(std::countr_zero(DESCRIPTOR_SIZE)); +constexpr u32 DYNAMIC_DESCRIPTOR_CBUF_BYTES = 16 * 1024; +constexpr u32 MAX_DYNAMIC_DESCRIPTOR_COUNT = 1024; + +u32 DynamicDescriptorSizeShift(const IR::U32& dynamic_offset) { + const IR::Inst* const inst{dynamic_offset.InstRecursive()}; + if (!inst || inst->GetOpcode() != IR::Opcode::ShiftLeftLogical32) { + return DESCRIPTOR_SIZE_SHIFT; + } + const IR::Value shift{inst->Arg(1)}; + if (!shift.IsImmediate()) { + return DESCRIPTOR_SIZE_SHIFT; + } + const u32 size_shift{shift.U32()}; + return size_shift >= DESCRIPTOR_SIZE_SHIFT && size_shift < 31 ? size_shift + : DESCRIPTOR_SIZE_SHIFT; +} + +u32 DynamicDescriptorCount(u32 base_offset, u32 size_shift) { + if (size_shift >= 31 || base_offset >= DYNAMIC_DESCRIPTOR_CBUF_BYTES) { + return 1; + } + const u32 stride{1U << size_shift}; + const u32 available{DYNAMIC_DESCRIPTOR_CBUF_BYTES - base_offset}; + if (available < DESCRIPTOR_SIZE) { + return 1; + } + const u32 available_count{1U + (available - DESCRIPTOR_SIZE) / stride}; + return std::min(MAX_DYNAMIC_DESCRIPTOR_COUNT, available_count); +} + +u32 SaturatingSub(u32 lhs, u32 rhs) { + return lhs > rhs ? lhs - rhs : 0; +} + +template +u32 StaticDescriptorCount(const Descriptors& descriptors) { + u32 count{}; + for (const auto& desc : descriptors) { + if (desc.count <= 1) { + count += desc.count; + } + } + return count; +} + +u32 DynamicSampledTextureCap(const Info& info, const HostTranslateInfo& host_info, + u32 dynamic_arrays) { + if (dynamic_arrays == 0) { + return MAX_DYNAMIC_DESCRIPTOR_COUNT; + } + const u32 sampled_static_count{StaticDescriptorCount(info.texture_buffer_descriptors) + + StaticDescriptorCount(info.texture_descriptors)}; + const u32 resource_static_count{ + NumDescriptors(info.constant_buffer_descriptors) + + NumDescriptors(info.storage_buffers_descriptors) + sampled_static_count + + NumDescriptors(info.image_buffer_descriptors) + NumDescriptors(info.image_descriptors)}; + const u32 sampled_limit{std::min(host_info.max_per_stage_descriptor_sampled_images, + host_info.max_descriptor_set_sampled_images)}; + const u32 sampled_budget{SaturatingSub(sampled_limit, sampled_static_count)}; + const u32 resource_budget{SaturatingSub(host_info.max_per_stage_resources, + resource_static_count)}; + const u32 sampled_cap{sampled_budget / dynamic_arrays}; + const u32 resource_cap{resource_budget / dynamic_arrays}; + return std::max(1U, std::min({MAX_DYNAMIC_DESCRIPTOR_COUNT, sampled_cap, resource_cap})); +} IR::Opcode IndexedInstruction(const IR::Inst& inst) { switch (inst.GetOpcode()) { @@ -109,6 +174,39 @@ IR::Opcode IndexedInstruction(const IR::Inst& inst) { } } +bool IsStorageImageOpcode(IR::Opcode opcode) { + switch (opcode) { + case IR::Opcode::ImageRead: + case IR::Opcode::ImageAtomicIAdd32: + case IR::Opcode::ImageAtomicSMin32: + case IR::Opcode::ImageAtomicUMin32: + case IR::Opcode::ImageAtomicSMax32: + case IR::Opcode::ImageAtomicUMax32: + case IR::Opcode::ImageAtomicInc32: + case IR::Opcode::ImageAtomicDec32: + case IR::Opcode::ImageAtomicAnd32: + case IR::Opcode::ImageAtomicOr32: + case IR::Opcode::ImageAtomicXor32: + case IR::Opcode::ImageAtomicExchange32: + case IR::Opcode::ImageWrite: + return true; + default: + return false; + } +} + +u32 DynamicSampledTextureArrayCount(const TextureInstVector& to_replace) { + u32 count{}; + for (const TextureInst& inst : to_replace) { + const auto flags{inst.inst->Flags()}; + if (inst.cbuf.count > 1 && !IsStorageImageOpcode(IndexedInstruction(*inst.inst)) && + flags.type != TextureType::Buffer) { + ++count; + } + } + return count; +} + bool IsBindless(const IR::Inst& inst) { switch (inst.GetOpcode()) { case IR::Opcode::BindlessImageSampleImplicitLod: @@ -354,6 +452,7 @@ std::optional TryGetConstBuffer(const IR::Inst* inst, Environme } else { return std::nullopt; } + const u32 size_shift{DynamicDescriptorSizeShift(dynamic_offset)}; return ConstBufferAddr{ .index = index.U32(), .offset = base_offset, @@ -362,7 +461,7 @@ std::optional TryGetConstBuffer(const IR::Inst* inst, Environme .secondary_offset = 0, .secondary_shift_left = 0, .dynamic_offset = dynamic_offset, - .count = 8, + .count = DynamicDescriptorCount(base_offset, size_shift), .has_secondary = false, }; } @@ -589,6 +688,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo program.info.texture_descriptors, program.info.image_descriptors, }; + const u32 sampled_dynamic_cap{ + DynamicSampledTextureCap(program.info, host_info, DynamicSampledTextureArrayCount(to_replace))}; for (TextureInst& texture_inst : to_replace) { // TODO: Handle arrays IR::Inst* const inst{texture_inst.inst}; @@ -632,6 +733,9 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo break; } u32 index; + const u32 size_shift{cbuf.count > 1 ? DynamicDescriptorSizeShift(cbuf.dynamic_offset) + : DESCRIPTOR_SIZE_SHIFT}; + u32 count{cbuf.count}; switch (inst->GetOpcode()) { case IR::Opcode::ImageRead: case IR::Opcode::ImageAtomicIAdd32: @@ -660,8 +764,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo .is_integer = is_integer, .cbuf_index = cbuf.index, .cbuf_offset = cbuf.offset, - .count = cbuf.count, - .size_shift = DESCRIPTOR_SIZE_SHIFT, + .count = count, + .size_shift = size_shift, }); } else { index = descriptors.Add(ImageDescriptor{ @@ -672,8 +776,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo .is_integer = is_integer, .cbuf_index = cbuf.index, .cbuf_offset = cbuf.offset, - .count = cbuf.count, - .size_shift = DESCRIPTOR_SIZE_SHIFT, + .count = count, + .size_shift = size_shift, }); } break; @@ -688,10 +792,11 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo .secondary_cbuf_index = cbuf.secondary_index, .secondary_cbuf_offset = cbuf.secondary_offset, .secondary_shift_left = cbuf.secondary_shift_left, - .count = cbuf.count, - .size_shift = DESCRIPTOR_SIZE_SHIFT, + .count = count, + .size_shift = size_shift, }); } else { + count = std::min(count, sampled_dynamic_cap); index = descriptors.Add(TextureDescriptor{ .type = flags.type, .is_depth = flags.is_depth != 0, @@ -703,8 +808,8 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo .secondary_cbuf_index = cbuf.secondary_index, .secondary_cbuf_offset = cbuf.secondary_offset, .secondary_shift_left = cbuf.secondary_shift_left, - .count = cbuf.count, - .size_shift = DESCRIPTOR_SIZE_SHIFT, + .count = count, + .size_shift = size_shift, }); } break; @@ -712,12 +817,12 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo flags.descriptor_index.Assign(index); inst->SetFlags(flags); - if (cbuf.count > 1) { + if (count > 1) { const auto insert_point{IR::Block::InstructionList::s_iterator_to(*inst)}; IR::IREmitter ir{*texture_inst.block, insert_point}; - const IR::U32 shift{ir.Imm32(DESCRIPTOR_SIZE_SHIFT)}; + const IR::U32 shift{ir.Imm32(size_shift)}; inst->SetArg(0, ir.UMin(ir.ShiftRightLogical(cbuf.dynamic_offset, shift), - ir.Imm32(DESCRIPTOR_SIZE - 1))); + ir.Imm32(count - 1))); } else { inst->SetArg(0, IR::Value{}); } diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 1a62324c95..490dd7acfe 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -127,9 +127,8 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, texture_cache.SynchronizeComputeDescriptors(); - static constexpr size_t max_elements = 64; - boost::container::static_vector views; - boost::container::static_vector samplers; + boost::container::small_vector views; + boost::container::small_vector samplers; const auto& qmd{kepler_compute.launch_description}; const auto& cbufs{qmd.const_buffer_config}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index adfe1614b1..087e985892 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -447,6 +447,9 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, .support_snorm_render_buffer = true, .support_viewport_index_layer = device.IsExtShaderViewportIndexLayerSupported(), .min_ssbo_alignment = static_cast(device.GetStorageBufferAlignment()), + .max_per_stage_descriptor_sampled_images = device.GetMaxPerStageDescriptorSampledImages(), + .max_per_stage_resources = device.GetMaxPerStageResources(), + .max_descriptor_set_sampled_images = device.GetMaxDescriptorSetSampledImages(), .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(), .support_conditional_barrier = device.SupportsConditionalBarriers(), }; diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index a8a89aee89..a5ffd08eac 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -335,6 +335,18 @@ public: return properties.properties.limits.maxDescriptorSetUniformBuffersDynamic; } + u32 GetMaxPerStageDescriptorSampledImages() const { + return properties.properties.limits.maxPerStageDescriptorSampledImages; + } + + u32 GetMaxPerStageResources() const { + return properties.properties.limits.maxPerStageResources; + } + + u32 GetMaxDescriptorSetSampledImages() const { + return properties.properties.limits.maxDescriptorSetSampledImages; + } + /// Returns float control properties of the device. const VkPhysicalDeviceFloatControlsPropertiesKHR& FloatControlProperties() const { return properties.float_controls; From 27e5cb0f126749d27935215a3c67ec338a0f06fc Mon Sep 17 00:00:00 2001 From: ryana Date: Mon, 4 May 2026 18:16:11 +0200 Subject: [PATCH 03/58] [spirv] mark sampled image descriptor indices non-uniform (#3900) fixes incorrect texture selection on vk when shaders use per-pixel descriptor indices, in line with #3898 so dynamic descs are no longer treated as uniform also fixes TD;LTD spotty grass issue on SD not addressed by above pr you can test out all the fixes here: https://git.eden-emu.dev/may/eden/src/branch/may/integrate-texture-descriptor-fixes Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3900 Reviewed-by: crueter --- .../backend/spirv/emit_spirv_image.cpp | 51 +++++++++++++++++-- src/shader_recompiler/profile.h | 4 ++ .../renderer_vulkan/vk_pipeline_cache.cpp | 2 + src/video_core/vulkan_common/vulkan_device.h | 5 ++ 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index c2511942d9..62a82dce9d 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -14,6 +14,38 @@ namespace Shader::Backend::SPIRV { namespace { +class DescriptorIndex { +public: + explicit DescriptorIndex(EmitContext& ctx, const IR::Value& index) + : id{index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index)}, + is_non_uniform{ctx.profile.support_sampled_image_array_nonuniform_indexing && + !index.IsImmediate()} { + if (!is_non_uniform) { + return; + } + if (ctx.profile.supported_spirv < 0x00010400) { + ctx.AddExtension("SPV_EXT_descriptor_indexing"); + } + ctx.AddCapability(spv::Capability::ShaderNonUniform); + ctx.AddCapability(spv::Capability::SampledImageArrayNonUniformIndexing); + Decorate(ctx, id); + } + + Id Value() const { + return id; + } + + void Decorate(EmitContext& ctx, Id object) const { + if (is_non_uniform) { + ctx.Decorate(object, spv::Decoration::NonUniform); + } + } + +private: + Id id; + bool is_non_uniform; +}; + class ImageOperands { public: [[maybe_unused]] static constexpr bool ImageSampleOffsetAllowed = false; @@ -189,8 +221,12 @@ private: Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR::Value& index) { const TextureDefinition& def{ctx.textures.at(info.descriptor_index)}; if (def.count > 1) { - const Id pointer{ctx.OpAccessChain(def.pointer_type, def.id, ctx.Def(index))}; - return ctx.OpLoad(def.sampled_type, pointer); + const DescriptorIndex idx{ctx, index}; + const Id pointer{ctx.OpAccessChain(def.pointer_type, def.id, idx.Value())}; + idx.Decorate(ctx, pointer); + const Id object{ctx.OpLoad(def.sampled_type, pointer)}; + idx.Decorate(ctx, object); + return object; } else { return ctx.OpLoad(def.sampled_type, def.id); } @@ -208,9 +244,14 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind } else { const TextureDefinition& def{ctx.textures.at(info.descriptor_index)}; if (def.count > 1) { - const Id idx{index.IsImmediate() ? ctx.Const(index.U32()) : ctx.Def(index)}; - const Id ptr{ctx.OpAccessChain(def.pointer_type, def.id, idx)}; - return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, ptr)); + const DescriptorIndex idx{ctx, index}; + const Id ptr{ctx.OpAccessChain(def.pointer_type, def.id, idx.Value())}; + idx.Decorate(ctx, ptr); + const Id object{ctx.OpLoad(def.sampled_type, ptr)}; + idx.Decorate(ctx, object); + const Id image{ctx.OpImage(def.image_type, object)}; + idx.Decorate(ctx, image); + return image; } return ctx.OpImage(def.image_type, ctx.OpLoad(def.sampled_type, def.id)); } diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index 90e46bb1ba..ff19f0710f 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -45,6 +48,7 @@ struct Profile { bool support_scaled_attributes{}; bool support_multi_viewport{}; bool support_geometry_streams{}; + bool support_sampled_image_array_nonuniform_indexing{}; bool warp_size_potentially_larger_than_guest{}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 087e985892..e365425600 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -412,6 +412,8 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, .support_scaled_attributes = !device.MustEmulateScaledFormats(), .support_multi_viewport = device.SupportsMultiViewport(), .support_geometry_streams = device.AreTransformFeedbackGeometryStreamsSupported(), + .support_sampled_image_array_nonuniform_indexing = + device.IsSampledImageArrayNonUniformIndexingSupported(), .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index a5ffd08eac..13fe1b371f 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -33,6 +33,7 @@ VK_DEFINE_HANDLE(VmaAllocator) FEATURE(KHR, VariablePointer, VARIABLE_POINTERS, variable_pointer) #define FOR_EACH_VK_FEATURE_1_2(FEATURE) \ + FEATURE(EXT, DescriptorIndexing, DESCRIPTOR_INDEXING, descriptor_indexing) \ FEATURE(EXT, HostQueryReset, HOST_QUERY_RESET, host_query_reset) \ FEATURE(KHR, 8BitStorage, 8BIT_STORAGE, bit8_storage) \ FEATURE(KHR, TimelineSemaphore, TIMELINE_SEMAPHORE, timeline_semaphore) @@ -367,6 +368,10 @@ public: return GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY; } + bool IsSampledImageArrayNonUniformIndexingSupported() const { + return features.descriptor_indexing.shaderSampledImageArrayNonUniformIndexing; + } + /// Returns true if the device supports float64 natively. bool IsFloat64Supported() const { return features.features.shaderFloat64; From 2deee80f290ad49106c27560c65969abae9beb8c Mon Sep 17 00:00:00 2001 From: PavelBARABANOV Date: Mon, 4 May 2026 19:54:26 +0200 Subject: [PATCH 04/58] [android] move GENSHIN_SPOOF flag to genshinSpoof flavor (#3923) The standard build was downloading the optimized APK and vice versa due to GENSHIN_SPOOF being incorrectly defined in the mainline flavor. This should resolve the issue. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3923 Reviewed-by: crueter --- src/android/app/build.gradle.kts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index 0519ac956d..ccc5b3cabe 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -192,12 +192,6 @@ android { manifestPlaceholders += mapOf("appNameBase" to "Eden") resValue("string", "app_name_suffixed", "Eden") - externalNativeBuild { - cmake { - arguments.add("-DGENSHIN_SPOOF=ON") - } - } - ndk { abiFilters += listOf("arm64-v8a") } @@ -209,6 +203,12 @@ android { resValue("string", "app_name_suffixed", "Eden Optimized") applicationId = "com.miHoYo.Yuanshen" + externalNativeBuild { + cmake { + arguments.add("-DGENSHIN_SPOOF=ON") + } + } + ndk { abiFilters += listOf("arm64-v8a") } From 17c341ff6c0f8be5d4e7614389456159cd247bd0 Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 4 May 2026 20:27:53 +0200 Subject: [PATCH 05/58] [video_core] index rescaling metadata by descriptor (#3899) (#3924) #3898 fix was good but exposed a rescaling metadata mismatch that can cause scaled texture descriptors to read the wrong state so this patch tries to keep them aligned with shader lookup Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3899 Reviewed-by: MaranBr Reviewed-by: crueter Co-authored-by: ryana Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3924 --- src/video_core/renderer_vulkan/pipeline_helper.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index e88b27b273..451a02c7e6 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -189,6 +189,7 @@ inline void PushImageDescriptors(TextureCache& texture_cache, views += num_texture_buffers; views += num_image_buffers; for (const auto& desc : info.texture_descriptors) { + bool is_rescaled{}; for (u32 index = 0; index < desc.count; ++index) { const VideoCommon::ImageViewId image_view_id{(views++)->id}; const VideoCommon::SamplerId sampler_id{*(samplers++)}; @@ -200,10 +201,13 @@ inline void PushImageDescriptors(TextureCache& texture_cache, const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy() : sampler.Handle()}; guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler); - rescaling.PushTexture(texture_cache.IsRescaling(image_view)); + const bool element_rescaled{texture_cache.IsRescaling(image_view)}; + is_rescaled |= element_rescaled; } + rescaling.PushTexture(is_rescaled); } for (const auto& desc : info.image_descriptors) { + bool is_rescaled{}; for (u32 index = 0; index < desc.count; ++index) { ImageView& image_view{texture_cache.GetImageView((views++)->id)}; if (desc.is_written) { @@ -211,8 +215,10 @@ inline void PushImageDescriptors(TextureCache& texture_cache, } const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)}; guest_descriptor_queue.AddImage(vk_image_view); - rescaling.PushImage(texture_cache.IsRescaling(image_view)); + const bool element_rescaled{texture_cache.IsRescaling(image_view)}; + is_rescaled |= element_rescaled; } + rescaling.PushImage(is_rescaled); } } From fc5fa7f1b2dc4a67f5cdff43e499991956692a56 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Mon, 4 May 2026 21:28:43 +0200 Subject: [PATCH 06/58] [video_core] Reapply "Simplify TextureCache GC and remove redundant code" (#3723) This enhances the garbage collection in TextureCache to make it more responsive and reliable during long gameplay sessions. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3723 Reviewed-by: crueter Reviewed-by: Lizzie Reviewed-by: CamilleLaVey --- src/video_core/texture_cache/texture_cache.h | 139 ++---------------- .../texture_cache/texture_cache_base.h | 1 - 2 files changed, 12 insertions(+), 128 deletions(-) diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index efae825885..5a1c680830 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -70,14 +70,10 @@ TextureCache

::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag (std::max)((std::min)(device_local_memory - min_vacancy_critical, min_spacing_critical), DEFAULT_CRITICAL_MEMORY)); minimum_memory = static_cast((device_local_memory - mem_threshold) / 2); - - lowmemorydevice = false; } else { expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB; critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB; minimum_memory = 0; - - lowmemorydevice = true; } const bool gpu_unswizzle_enabled = Settings::values.gpu_unswizzle_enabled.GetValue(); @@ -122,102 +118,48 @@ void TextureCache

::RunGarbageCollector() { bool aggressive_mode = false; u64 ticks_to_destroy = 0; size_t num_iterations = 0; - const auto Configure = [&](bool allow_aggressive) { high_priority_mode = total_used_memory >= expected_memory; aggressive_mode = allow_aggressive && total_used_memory >= critical_memory; ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 50ULL; num_iterations = aggressive_mode ? 40 : (high_priority_mode ? 20 : 10); }; - - const auto Cleanup = [this, &num_iterations, &high_priority_mode, - &aggressive_mode](ImageId image_id) { + const auto Cleanup = [this, &num_iterations, &high_priority_mode, &aggressive_mode](ImageId image_id) { if (num_iterations == 0) { return true; } - --num_iterations; auto& image = slot_images[image_id]; - - // Never delete recently allocated sparse textures (within 3 frames) - const bool is_recently_allocated = image.allocation_tick >= frame_tick - 3; - if (is_recently_allocated && image.info.is_sparse) { - return false; - } - if (True(image.flags & ImageFlagBits::IsDecoding)) { - // This image is still being decoded, deleting it will invalidate the slot - // used by the async decoder thread. return false; } - - // Prioritize large sparse textures for cleanup - const bool is_large_sparse = lowmemorydevice && - image.info.is_sparse && - image.guest_size_bytes >= 256_MiB; - - if (!aggressive_mode && !is_large_sparse && - True(image.flags & ImageFlagBits::CostlyLoad)) { + const bool must_download = image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap); + if ((!aggressive_mode && True(image.flags & ImageFlagBits::CostlyLoad)) || (!high_priority_mode && must_download)) { return false; } - - const bool must_download = - image.IsSafeDownload() && False(image.flags & ImageFlagBits::BadOverlap); - if (!high_priority_mode && !is_large_sparse && must_download) { - return false; - } - - if (must_download && !is_large_sparse) { + --num_iterations; + if (must_download) { auto map = runtime.DownloadStagingBuffer(image.unswizzled_size_bytes); const auto copies = FixSmallVectorADL(FullDownloadCopies(image.info)); image.DownloadMemory(map, copies); runtime.Finish(); - SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span, - swizzle_data_buffer); + SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span, swizzle_data_buffer); } - if (True(image.flags & ImageFlagBits::Tracked)) { UntrackImage(image, image_id); } UnregisterImage(image_id); DeleteImage(image_id, image.scale_tick > frame_tick + 5); - - if (total_used_memory < critical_memory) { - if (aggressive_mode) { - // Sink the aggresiveness. - num_iterations >>= 2; - aggressive_mode = false; - return false; - } - if (high_priority_mode && total_used_memory < expected_memory) { - num_iterations >>= 1; - high_priority_mode = false; - } + if (aggressive_mode && total_used_memory < critical_memory) { + num_iterations >>= 2; + aggressive_mode = false; + } else if (high_priority_mode && total_used_memory < expected_memory) { + num_iterations >>= 1; + high_priority_mode = false; } return false; }; - - // Aggressively clear massive sparse textures - if (total_used_memory >= expected_memory) { - lru_cache.ForEachItemBelow(frame_tick, [&](ImageId image_id) { - auto& image = slot_images[image_id]; - // Only target sparse textures that are old enough - if (lowmemorydevice && - image.info.is_sparse && - image.guest_size_bytes >= 256_MiB && - image.allocation_tick < frame_tick - 3) { - LOG_DEBUG(HW_GPU, "GC targeting old sparse texture at 0x{:X} ({} MiB, age: {} frames)", - image.gpu_addr, image.guest_size_bytes / (1024 * 1024), - frame_tick - image.allocation_tick); - return Cleanup(image_id); - } - return false; - }); - } - Configure(false); lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, Cleanup); - - // If pressure is still too high, prune aggressively. if (total_used_memory >= critical_memory) { Configure(true); lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, Cleanup); @@ -1196,9 +1138,6 @@ void TextureCache

::RefreshContents(Image& image, ImageId image_id) { } image.flags &= ~ImageFlagBits::CpuModified; - if( lowmemorydevice && image.info.format == PixelFormat::BC1_RGBA_UNORM && MapSizeBytes(image) >= 256_MiB ) { - return; - } TrackImage(image, image_id); @@ -1619,39 +1558,6 @@ ImageId TextureCache

::InsertImage(const ImageInfo& info, GPUVAddr gpu_addr, } } ASSERT_MSG(cpu_addr, "Tried to insert an image to an invalid gpu_addr=0x{:x}", gpu_addr); - - // For large sparse textures, aggressively clean up old allocations at same address - if (lowmemorydevice && info.is_sparse && CalculateGuestSizeInBytes(info) >= 256_MiB) { - const auto alloc_it = image_allocs_table.find(gpu_addr); - if (alloc_it != image_allocs_table.end()) { - const ImageAllocId alloc_id = alloc_it->second; - auto& alloc_images = slot_image_allocs[alloc_id].images; - - // Collect old images at this address that were created more than 2 frames ago - boost::container::small_vector to_delete; - for (ImageId old_image_id : alloc_images) { - Image& old_image = slot_images[old_image_id]; - if (old_image.info.is_sparse && - old_image.gpu_addr == gpu_addr && - old_image.allocation_tick < frame_tick - 2) { // Try not to delete fresh textures - to_delete.push_back(old_image_id); - } - } - - // Delete old images immediately - for (ImageId old_id : to_delete) { - Image& old_image = slot_images[old_id]; - LOG_DEBUG(HW_GPU, "Immediately deleting old sparse texture at 0x{:X} ({} MiB)", - gpu_addr, old_image.guest_size_bytes / (1024 * 1024)); - if (True(old_image.flags & ImageFlagBits::Tracked)) { - UntrackImage(old_image, old_id); - } - UnregisterImage(old_id); - DeleteImage(old_id, true); - } - } - } - const ImageId image_id = JoinImages(info, gpu_addr, *cpu_addr); const Image& image = slot_images[image_id]; // Using "image.gpu_addr" instead of "gpu_addr" is important because it might be different @@ -1667,27 +1573,6 @@ template ImageId TextureCache

::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DAddr cpu_addr) { ImageInfo new_info = info; const size_t size_bytes = CalculateGuestSizeInBytes(new_info); - - // Proactive cleanup for large sparse texture allocations - if (lowmemorydevice && new_info.is_sparse && size_bytes >= 256_MiB) { - const u64 estimated_alloc_size = size_bytes; - - if (total_used_memory + estimated_alloc_size >= critical_memory) { - LOG_DEBUG(HW_GPU, "Large sparse texture allocation ({} MiB) - running aggressive GC. " - "Current memory: {} MiB, Critical: {} MiB", - size_bytes / (1024 * 1024), - total_used_memory / (1024 * 1024), - critical_memory / (1024 * 1024)); - RunGarbageCollector(); - - // If still over threshold after GC, try one more aggressive pass - if (total_used_memory + estimated_alloc_size >= critical_memory) { - LOG_DEBUG(HW_GPU, "Still critically low on memory, running second GC pass"); - RunGarbageCollector(); - } - } - } - const bool broken_views = runtime.HasBrokenTextureViewFormats(); const bool native_bgr = runtime.HasNativeBgr(); join_overlap_ids.clear(); diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 4b4061f21d..47f52c5c99 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -478,7 +478,6 @@ private: u64 minimum_memory; u64 expected_memory; u64 critical_memory; - bool lowmemorydevice = false; size_t gpu_unswizzle_maxsize = 0; size_t swizzle_chunk_size = 0; u32 swizzle_slices_per_batch = 0; From fee603f0b97d2d8a6ecb793326e844e066d2f4cf Mon Sep 17 00:00:00 2001 From: maufeat Date: Tue, 5 May 2026 01:29:46 +0200 Subject: [PATCH 07/58] [kernel, hle] Initial 22.0.0 kernel changes and cmd stubs (#3761) - KProcess::Run() and CreateThread() SVC now write the current thread handle to TLS+0x110 - KPageTableBase::LockForMapDeviceAddressSpace now checks for a new KPageTableBase boolean, m_allowed_exec_device_mapping - Stub `am` + `acc` + `settings` cmd module that needs to work for qlaunch Thanks to: @alula and @yellows8 Source for changes: https://github.com/Atmosphere-NX/Atmosphere/pull/2744, https://switchbrew.org/, https://yls8.mtheall.com/ Co-authored-by: PavelBARABANOV Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3761 Reviewed-by: CamilleLaVey --- src/core/hle/kernel/k_page_table_base.cpp | 1 + src/core/hle/kernel/k_page_table_base.h | 5 +++ src/core/hle/kernel/k_process.cpp | 13 +++++++ src/core/hle/kernel/k_process_page_table.h | 4 ++ src/core/hle/kernel/k_thread.cpp | 38 ++++++++++--------- src/core/hle/kernel/svc/svc_thread.cpp | 9 ++++- src/core/hle/kernel/svc_version.h | 6 +-- src/core/hle/service/acc/acc.cpp | 8 ++++ src/core/hle/service/acc/acc.h | 3 +- src/core/hle/service/acc/acc_su.cpp | 4 +- src/core/hle/service/acc/acc_u1.cpp | 5 ++- .../am/service/application_creator.cpp | 4 +- .../am/service/common_state_getter.cpp | 15 +++++++- .../service/am/service/common_state_getter.h | 4 +- .../am/service/library_applet_accessor.cpp | 7 ++++ .../am/service/library_applet_accessor.h | 3 +- .../am/service/library_applet_creator.cpp | 5 ++- src/core/hle/service/set/settings_types.h | 7 ++++ .../service/set/system_settings_server.cpp | 21 +++++++++- .../hle/service/set/system_settings_server.h | 6 ++- 20 files changed, 130 insertions(+), 38 deletions(-) diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index e5b2ed7041..3696f9f251 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp @@ -268,6 +268,7 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool // Set other basic fields. m_enable_aslr = enable_aslr; m_enable_device_address_space_merge = enable_das_merge; + m_allowed_exec_device_mapping = false; m_address_space_start = start; m_address_space_end = end; m_is_kernel = false; diff --git a/src/core/hle/kernel/k_page_table_base.h b/src/core/hle/kernel/k_page_table_base.h index 90f8124a24..726fad989f 100644 --- a/src/core/hle/kernel/k_page_table_base.h +++ b/src/core/hle/kernel/k_page_table_base.h @@ -223,6 +223,7 @@ private: bool m_is_kernel{}; bool m_enable_aslr{}; bool m_enable_device_address_space_merge{}; + bool m_allowed_exec_device_mapping{}; KMemoryBlockSlabManager* m_memory_block_slab_manager{}; KBlockInfoManager* m_block_info_manager{}; KResourceLimit* m_resource_limit{}; @@ -255,6 +256,10 @@ public: return m_enable_aslr; } + void AllowDeviceMappingOfExecPages() { + m_allowed_exec_device_mapping = true; + } + bool Contains(KProcessAddress addr) const { return m_address_space_start <= addr && addr <= m_address_space_end - 1; } diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index bd50f74c27..70e578f22a 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -341,6 +341,11 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa // Initialize capabilities. R_TRY(m_capabilities.InitializeForKip(caps, std::addressof(m_page_table))); + // Enable mapping device pages as executable on legacy processes. + if (m_capabilities.GetIntendedKernelMajorVersion() < 26) { + m_page_table.AllowDeviceMappingOfExecPages(); + } + // Initialize the process id. m_process_id = m_kernel.CreateNewUserProcessID(); ASSERT(InitialProcessIdMin <= m_process_id); @@ -437,6 +442,11 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, // Initialize capabilities. R_TRY(m_capabilities.InitializeForUser(user_caps, std::addressof(m_page_table))); + // Enable mapping device pages as executable on legacy processes. + if (m_capabilities.GetIntendedKernelMajorVersion() < 26) { + m_page_table.AllowDeviceMappingOfExecPages(); + } + // Initialize the process id. m_process_id = m_kernel.CreateNewUserProcessID(); ASSERT(ProcessIdMin <= m_process_id); @@ -989,6 +999,9 @@ Result KProcess::Run(s32 priority, size_t stack_size) { main_thread->GetContext().r[0] = 0; main_thread->GetContext().r[1] = thread_handle; + // Pass the thread handle to the thread local region. + this->GetMemory().Write32(GetInteger(main_thread->GetTlsAddress()) + 0x110, thread_handle); + // Update our state. this->ChangeState((state == State::Created) ? State::Running : State::RunningAttached); ON_RESULT_FAILURE_2 { diff --git a/src/core/hle/kernel/k_process_page_table.h b/src/core/hle/kernel/k_process_page_table.h index 6462e44a99..97c9238907 100644 --- a/src/core/hle/kernel/k_process_page_table.h +++ b/src/core/hle/kernel/k_process_page_table.h @@ -33,6 +33,10 @@ public: m_page_table.Finalize(); } + void AllowDeviceMappingOfExecPages() { + m_page_table.AllowDeviceMappingOfExecPages(); + } + [[nodiscard]] Core::Memory::Memory& GetMemory() noexcept { return m_page_table.GetMemory(); } [[nodiscard]] Core::Memory::Memory const& GetMemory() const noexcept { return m_page_table.GetMemory(); } [[nodiscard]] Common::PageTable& GetImpl() noexcept { return m_page_table.GetImpl(); } diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index ea9b7eb114..0af315d726 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -76,11 +76,13 @@ namespace Kernel { std::atomic_uint16_t interrupt_flag; std::atomic_uint8_t cache_maintenance_flag; std::atomic_int64_t thread_cpu_time; + std::atomic_uint32_t current_thread_handle; }; static_assert(offsetof(ThreadLocalRegion, disable_count) == 0x100); static_assert(offsetof(ThreadLocalRegion, interrupt_flag) == 0x102); static_assert(offsetof(ThreadLocalRegion, cache_maintenance_flag) == 0x104); static_assert(offsetof(ThreadLocalRegion, thread_cpu_time) == 0x108); + static_assert(offsetof(ThreadLocalRegion, current_thread_handle) == 0x110); class ThreadQueueImplForKThreadSleep final : public KThreadQueueWithoutEndWait { public: @@ -128,24 +130,24 @@ namespace Kernel { // Next, assert things based on the type. switch (type) { - case ThreadType::Main: - ASSERT(arg == 0); - [[fallthrough]]; - case ThreadType::User: - ASSERT(((owner == nullptr) || - (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask())); - ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) || - (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask())); - break; - case ThreadType::HighPriority: - case ThreadType::Dummy: - break; - case ThreadType::Kernel: - UNIMPLEMENTED(); - break; - default: - ASSERT_MSG(false, "KThread::Initialize: Unknown ThreadType {}", static_cast(type)); - break; + case ThreadType::Main: + ASSERT(arg == 0); + [[fallthrough]]; + case ThreadType::User: + ASSERT(((owner == nullptr) || + (owner->GetCoreMask() | (1ULL << virt_core)) == owner->GetCoreMask())); + ASSERT(((owner == nullptr) || (prio > Svc::LowestThreadPriority) || + (owner->GetPriorityMask() | (1ULL << prio)) == owner->GetPriorityMask())); + break; + case ThreadType::HighPriority: + case ThreadType::Dummy: + break; + case ThreadType::Kernel: + UNIMPLEMENTED(); + break; + default: + ASSERT_MSG(false, "KThread::Initialize: Unknown ThreadType {}", static_cast(type)); + break; } m_thread_type = type; diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index ca5ce6fe07..1aa6f87c04 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp @@ -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: Copyright 2023 yuzu Emulator Project @@ -75,7 +75,12 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u KThread::Register(kernel, thread); // Add the thread to the handle table. - R_RETURN(process.GetHandleTable().Add(out_handle, thread)); + R_TRY(process.GetHandleTable().Add(out_handle, thread)); + + // Pass the thread handle to the thread local region. + process.GetMemory().Write32(GetInteger(thread->GetTlsAddress()) + 0x110, *out_handle); + + R_SUCCEED(); } /// Starts the thread for the provided handle diff --git a/src/core/hle/kernel/svc_version.h b/src/core/hle/kernel/svc_version.h index b47874dcde..ec5c5a006a 100644 --- a/src/core/hle/kernel/svc_version.h +++ b/src/core/hle/kernel/svc_version.h @@ -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: Copyright 2023 yuzu Emulator Project @@ -53,8 +53,8 @@ constexpr inline u32 RequiredKernelVersion = // This is the highest SVC version supported, to be updated on new kernel releases. // NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. -constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(20); -constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion(5); +constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(22); +constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion(2); constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 43c569851d..c33b765000 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -1155,6 +1155,14 @@ void Module::Interface::StoreSaveDataThumbnailSystem(HLERequestContext& ctx) { StoreSaveDataThumbnail(ctx, uuid, tid); } +void Module::Interface::GetPinCodeLength(HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(0); +} + void Module::Interface::StoreSaveDataThumbnail(HLERequestContext& ctx, const Common::UUID& uuid, const u64 tid) { IPC::ResponseBuilder rb{ctx, 2}; diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index b01998e9c9..19af7c74c9 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h @@ -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: Copyright 2018 yuzu Emulator Project @@ -48,6 +48,7 @@ public: void StoreSaveDataThumbnailApplication(HLERequestContext& ctx); void GetBaasAccountManagerForSystemService(HLERequestContext& ctx); void StoreSaveDataThumbnailSystem(HLERequestContext& ctx); + void GetPinCodeLength(HLERequestContext& ctx); private: Result InitializeApplicationInfoBase(); diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp index 9eea0ea2ed..195af7ff69 100644 --- a/src/core/hle/service/acc/acc_su.cpp +++ b/src/core/hle/service/acc/acc_su.cpp @@ -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: Copyright 2018 yuzu Emulator Project @@ -60,7 +60,7 @@ ACC_SU::ACC_SU(std::shared_ptr module_, std::shared_ptr {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"}, {299, nullptr, "SuspendBackgroundDaemon"}, {400, nullptr, "SetPinCode"}, // 18.0.0+ - {401, nullptr, "GetPinCodeLength"}, // 18.0.0+ + {401, &ACC_SU::GetPinCodeLength, "GetPinCodeLength"}, // 18.0.0+ {402, nullptr, "GetPinCode"}, // 18.0.0+ {410, nullptr, "GetPinCodeErrorCount"}, // 18.0.0+ {411, nullptr, "ResetPinCodeErrorCount"}, // 18.0.0+ diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp index 3832f5216d..c39e916366 100644 --- a/src/core/hle/service/acc/acc_u1.cpp +++ b/src/core/hle/service/acc/acc_u1.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -40,7 +43,7 @@ ACC_U1::ACC_U1(std::shared_ptr module_, std::shared_ptr {152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"}, {190, nullptr, "GetUserLastOpenedApplication"}, {191, nullptr, "ActivateOpenContextHolder"}, - {401, nullptr, "GetPinCodeLength"}, // 18.0.0+ + {401, &ACC_U1::GetPinCodeLength, "GetPinCodeLength"}, // 18.0.0+ {402, nullptr, "GetPinCode"}, // 18.0.0+ {997, nullptr, "DebugInvalidateTokenCacheForUser"}, {998, nullptr, "DebugSetUserStateClose"}, diff --git a/src/core/hle/service/am/service/application_creator.cpp b/src/core/hle/service/am/service/application_creator.cpp index d16fd7dd84..81620a5067 100644 --- a/src/core/hle/service/am/service/application_creator.cpp +++ b/src/core/hle/service/am/service/application_creator.cpp @@ -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: Copyright 2024 yuzu Emulator Project @@ -92,7 +92,7 @@ Result IApplicationCreator::CreateSystemApplication( std::unique_ptr loader; auto process = - CreateProcess(system, application_id, 1, 21); + CreateProcess(system, application_id, 1, 22); R_UNLESS(process != nullptr, ResultUnknown); const auto applet = std::make_shared(system, std::move(process), true); diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp index 0af5b31714..5b5e21b8e0 100644 --- a/src/core/hle/service/am/service/common_state_getter.cpp +++ b/src/core/hle/service/am/service/common_state_getter.cpp @@ -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: Copyright 2024 yuzu Emulator Project @@ -75,7 +75,8 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr, "Unknown610"}, //21.0.0+ + {611, D<&ICommonStateGetter::Unknown611>, "Unknown611"}, //22.0.0+ {900, D<&ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled>, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, //11.0.0+ {910, nullptr, "GetLaunchRequiredTick"}, //17.0.0+ {1000, nullptr, "BeginVrMode3d"}, //19.0.0+ @@ -362,4 +363,14 @@ Result ICommonStateGetter::SetHandlingHomeButtonShortPressedEnabled(bool enabled R_SUCCEED(); } +Result ICommonStateGetter::Unknown610() { + LOG_WARNING(Service_AM, "(STUBBED) called"); + R_SUCCEED(); +} + +Result ICommonStateGetter::Unknown611() { + LOG_WARNING(Service_AM, "(STUBBED) called"); + R_SUCCEED(); +} + } // namespace Service::AM diff --git a/src/core/hle/service/am/service/common_state_getter.h b/src/core/hle/service/am/service/common_state_getter.h index a98024182f..c1bec4f2a2 100644 --- a/src/core/hle/service/am/service/common_state_getter.h +++ b/src/core/hle/service/am/service/common_state_getter.h @@ -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: Copyright 2024 yuzu Emulator Project @@ -63,6 +63,8 @@ private: Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(); Result PushToGeneralChannel(SharedPointer storage); // cmd 20 Result SetHandlingHomeButtonShortPressedEnabled(bool enabled); + Result Unknown610(); + Result Unknown611(); void SetCpuBoostMode(HLERequestContext& ctx); diff --git a/src/core/hle/service/am/service/library_applet_accessor.cpp b/src/core/hle/service/am/service/library_applet_accessor.cpp index c5b6929ab3..ef91f69c23 100644 --- a/src/core/hle/service/am/service/library_applet_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_accessor.cpp @@ -78,6 +78,7 @@ ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, {120, nullptr, "GetLibraryAppletInfo"}, {150, nullptr, "RequestForAppletToGetForeground"}, {160, D<&ILibraryAppletAccessor::GetIndirectLayerConsumerHandle>, "GetIndirectLayerConsumerHandle"}, //2.0.0+ + {170, D<&ILibraryAppletAccessor::Unknown170>, "Unknown170"}, //22.0.0+ }; // clang-format on @@ -217,6 +218,12 @@ Result ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(Out out_handl R_SUCCEED(); } +Result ILibraryAppletAccessor::Unknown170(OutCopyHandle out_event) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + *out_event = m_applet->unknown_event.GetHandle(); + R_SUCCEED(); +} + void ILibraryAppletAccessor::FrontendExecute() { if (m_applet->frontend) { m_applet->frontend->Initialize(); diff --git a/src/core/hle/service/am/service/library_applet_accessor.h b/src/core/hle/service/am/service/library_applet_accessor.h index 841d0d5146..02fcd07fd3 100644 --- a/src/core/hle/service/am/service/library_applet_accessor.h +++ b/src/core/hle/service/am/service/library_applet_accessor.h @@ -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: Copyright 2024 yuzu Emulator Project @@ -37,6 +37,7 @@ private: Result GetPopOutDataEvent(OutCopyHandle out_event); Result GetPopInteractiveOutDataEvent(OutCopyHandle out_event); Result GetIndirectLayerConsumerHandle(Out out_handle); + Result Unknown170(OutCopyHandle out_event); void FrontendExecute(); void FrontendExecuteInteractive(); diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp index e38729e70a..3de5740237 100644 --- a/src/core/hle/service/am/service/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp @@ -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: Copyright 2024 yuzu Emulator Project @@ -118,9 +118,10 @@ std::shared_ptr CreateGuestApplet(Core::System& system, Firmware1900 = 19, Firmware2000 = 20, Firmware2100 = 21, + Firmware2200 = 22, }; - auto process = CreateProcess(system, program_id, Firmware1400, Firmware2100); + auto process = CreateProcess(system, program_id, Firmware1400, Firmware2200); if (!process) { // Couldn't initialize the guest process return {}; diff --git a/src/core/hle/service/set/settings_types.h b/src/core/hle/service/set/settings_types.h index 469b8d745c..696938c4c7 100644 --- a/src/core/hle/service/set/settings_types.h +++ b/src/core/hle/service/set/settings_types.h @@ -409,6 +409,13 @@ struct AccountNotificationSettings { static_assert(sizeof(AccountNotificationSettings) == 0x18, "AccountNotificationSettings is an invalid size"); +/// This is nn::settings::system::AccountUserSettings (stubbed) +struct AccountUserSettings { + std::array data; +}; +static_assert(sizeof(AccountUserSettings) == 0x40, + "AccountUserSettings is an invalid size"); + /// This is nn::settings::factory::BatteryLot struct BatteryLot { std::array lot_number; diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index c7a83e69f4..0ed6d28dd4 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -340,9 +340,9 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {306, nullptr, "GetPinCodeReregistrationGuideAccounts"}, //20.0.0+ {307, nullptr, "SetPinCodeReregistrationGuideAccounts"}, //20.0.0+ {315, C<&ISystemSettingsServer::GetHttpAuthConfigs>, "GetHttpAuthConfigs"}, //21.0.0+ - {319, nullptr, "GetAccountUserSettings"}, //21.0.0+ + {319, C<&ISystemSettingsServer::GetAccountUserSettings>, "GetAccountUserSettings"}, //21.0.0+ {320, nullptr, "SetAccountUserSettings"}, //21.0.0+ - {321, nullptr, "GetDefaultAccountUserSettings"}, //21.0.0+ + {321, C<&ISystemSettingsServer::GetDefaultAccountUserSettings>, "GetDefaultAccountUserSettings"}, //21.0.0+ }; // clang-format on @@ -1428,6 +1428,23 @@ Result ISystemSettingsServer::GetHttpAuthConfigs(Out out_count, OutBuffer out_count, + OutLargeData out_settings) { + LOG_WARNING(Service_SET, "(STUBBED) called"); + + *out_count = 0; + *out_settings = {}; + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetDefaultAccountUserSettings(Out out_settings) { + LOG_WARNING(Service_SET, "(STUBBED) called"); + + *out_settings = {}; + R_SUCCEED(); +} + void ISystemSettingsServer::SetupSettings() { auto system_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir) / "system/save/8000000000000050"; if (!LoadSettingsFile(system_dir, []() { return DefaultSystemSettings(); })) { diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index 27a16747f3..2a160dfc6b 100644 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h @@ -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: Copyright 2018 yuzu Emulator Project @@ -161,6 +161,10 @@ public: Result GetPanelCrcMode(Out out_panel_crc_mode); Result SetPanelCrcMode(s32 panel_crc_mode); Result GetHttpAuthConfigs(Out out_count, OutBuffer out_configs); + Result GetAccountUserSettings( + Out out_count, + OutLargeData out_settings); + Result GetDefaultAccountUserSettings(Out out_settings); private: bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func); From 4f4c298a39fee558f2a593157192afe7f821014c Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 5 May 2026 07:31:08 +0200 Subject: [PATCH 08/58] [hle, service] fix errors related to race conditions triggering under SMG1 and SMG2 (#3927) - service manager may add a service while someone else is finding it, so properly lock - nvhost doesn't properly account for the fact that iterators GET FUCKING INVALIDATED - use proper exit routine for mapping locked that failed (try/catch hell) the last two were introduced by #3858, but the first one has been present since ??? either way, remember that ankerl map has invalidated iterators upon erase/insert, so i accounted for that and SMG1 (and probably smg2) boot fine now Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3927 Reviewed-by: crueter Reviewed-by: CamilleLaVey --- .../service/nvdrv/devices/nvhost_as_gpu.cpp | 46 ++++++++++--------- .../hle/service/nvdrv/devices/nvhost_as_gpu.h | 2 +- src/core/hle/service/sm/sm.h | 20 ++++---- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index df0339ba85..3bfef0c29c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -199,25 +199,28 @@ NvResult nvhost_as_gpu::AllocateSpace(IoctlAllocSpace& params) { return NvResult::Success; } -void nvhost_as_gpu::FreeMappingLocked(u64 offset) { - auto const it = mapping_map.find(offset); - auto const mapping = it->second; - if (!mapping.fixed) { - auto& allocator{mapping.big_page ? *vm.big_page_allocator : *vm.small_page_allocator}; - u32 page_size_bits{mapping.big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS}; - u32 page_size{mapping.big_page ? vm.big_page_size : VM::YUZU_PAGESIZE}; - u64 aligned_size{Common::AlignUp(mapping.size, page_size)}; - allocator.Free(u32(mapping.offset >> page_size_bits), u32(aligned_size >> page_size_bits)); +bool nvhost_as_gpu::FreeMappingLocked(u64 offset) noexcept { + if (auto const it = mapping_map.find(offset); it != mapping_map.end()) { + auto const mapping = it->second; + if (!mapping.fixed) { + auto& allocator{mapping.big_page ? *vm.big_page_allocator : *vm.small_page_allocator}; + u32 page_size_bits{mapping.big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS}; + u32 page_size{mapping.big_page ? vm.big_page_size : VM::YUZU_PAGESIZE}; + u64 aligned_size{Common::AlignUp(mapping.size, page_size)}; + allocator.Free(u32(mapping.offset >> page_size_bits), u32(aligned_size >> page_size_bits)); + } + nvmap.UnpinHandle(mapping.handle); + // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state + // Only FreeSpace can unmap them fully + if (mapping.sparse_alloc) { + gmmu->MapSparse(offset, mapping.size, mapping.big_page); + } else { + gmmu->Unmap(offset, mapping.size); + } + mapping_map.erase(offset); + return true; } - nvmap.UnpinHandle(mapping.handle); - // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state - // Only FreeSpace can unmap them fully - if (mapping.sparse_alloc) { - gmmu->MapSparse(offset, mapping.size, mapping.big_page); - } else { - gmmu->Unmap(offset, mapping.size); - } - mapping_map.erase(it); + return false; } NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) { @@ -232,7 +235,8 @@ NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) { return NvResult::BadValue; for (const auto mapping_offset : allocation.mappings) - FreeMappingLocked(mapping_offset); + if (!FreeMappingLocked(mapping_offset)) + return NvResult::BadValue; // Unset sparse flag if required if (allocation.sparse) @@ -402,8 +406,8 @@ NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) { } nvmap.UnpinHandle(mapping.handle); - mapping_map.erase(it); - map_buffer_offsets.erase(offset_it); + mapping_map.erase(params.offset); + map_buffer_offsets.erase(params.offset); } return NvResult::Success; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index 862bdd60bf..44892ee368 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h @@ -157,7 +157,7 @@ private: NvResult GetVARegions1(IoctlGetVaRegions& params); NvResult GetVARegions3(IoctlGetVaRegions& params, std::span regions); - void FreeMappingLocked(u64 offset); + [[nodiscard]] bool FreeMappingLocked(u64 offset) noexcept; Module& module; diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 039d53ebf8..65e6876926 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -67,22 +67,24 @@ public: Result GetServicePort(Kernel::KClientPort** out_client_port, const std::string& name); template T> - std::shared_ptr GetService(const std::string& service_name, bool block = false) const { - auto service = registered_services.find(service_name); - if (service == registered_services.end() && !block) { - LOG_DEBUG(Service, "Can't find service: {}", service_name); + std::shared_ptr GetService(const std::string& name, bool block = false) const { + std::unique_lock l{lock}; + auto it = registered_services.find(name); + if (it == registered_services.end() && !block) { + LOG_DEBUG(Service, "Can't find service: {}", name); return nullptr; } else if (block) { using namespace std::literals::chrono_literals; - while (service == registered_services.end()) { + while (it == registered_services.end()) { + l.unlock(); Kernel::Svc::SleepThread( kernel.System(), std::chrono::duration_cast(100ms).count()); - service = registered_services.find(service_name); + l.lock(); + it = registered_services.find(name); } } - - return std::static_pointer_cast(service->second()); + return std::static_pointer_cast(it->second()); } void InvokeControlRequest(HLERequestContext& context); @@ -96,7 +98,7 @@ private: std::unique_ptr controller_interface; /// Map of registered services, retrieved using GetServicePort. - std::mutex lock; + mutable std::mutex lock; ankerl::unordered_dense::map registered_services; ankerl::unordered_dense::map service_ports; From 8f4e8c6d6abc3c85a812891bd3df740dfea7fe7c Mon Sep 17 00:00:00 2001 From: Eden CI Date: Tue, 5 May 2026 21:48:58 +0200 Subject: [PATCH 09/58] [dist, android] Update translations from Transifex for May 05 (#3929) Automatic translation update for May 05 Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3929 --- dist/languages/ru_RU.ts | 2 +- src/android/app/src/main/res/values-fr/strings.xml | 2 ++ src/android/app/src/main/res/values-ru/strings.xml | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dist/languages/ru_RU.ts b/dist/languages/ru_RU.ts index 5fb35d0956..56d893d688 100644 --- a/dist/languages/ru_RU.ts +++ b/dist/languages/ru_RU.ts @@ -3403,7 +3403,7 @@ Would you like to delete the old save data? Vulkan Extensions - Расшиерния Vulcan + Расширения Vulcan diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml index df16737dec..0f41841fb5 100644 --- a/src/android/app/src/main/res/values-fr/strings.xml +++ b/src/android/app/src/main/res/values-fr/strings.xml @@ -413,7 +413,9 @@ Limiter le pourcentage de vitesse Spécifier le pourcentage pour limiter la vitesse d\'émulation. 100% correspond à la vitesse normale. Des valeurs plus élevées ou plus basses augmenteront ou diminueront la limite de vitesse. Vitesse turbo + Lorsque le mode Turbo est activé, l\'émulation s\'exécute à cette vitesse. Vitesse lente + Lorsque le mode Lent est activé, l\'émulation s\'exécute à cette vitesse. Backend du CPU Précision du CPU %1$s%2$s diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml index caa30851a0..dbce577e13 100644 --- a/src/android/app/src/main/res/values-ru/strings.xml +++ b/src/android/app/src/main/res/values-ru/strings.xml @@ -489,6 +489,8 @@ Включить историю буфера Позволяет обращаться к предыдущим состояниям буфера. Эта опция может повысить качество рендеринга и стабильность производительности в некоторых играх. Оптимизированные вершинные буферы + Включает оптимизированную привязку вершинного буфера для повышения производительности. Требует Mesa Turnip 26.0+ / QCOM драйверы. Приводит к вылету на старых версиях Turnip. + Хаки Быстрое время ГПУ @@ -496,6 +498,9 @@ Пропустить внутреннюю инвалидацию ЦП Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх. Исправить эффекты размытия + Частично убирает размытие в LA/EOW (Adreno A6XX - A7XX/ Turnip), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх. + Эмулировать BGR565 + Исправляет проблемы с инвертированными цветами в играх, а также со странными артефактами или некорректными тенями. Использовать асинхронные шейдеры Компилирует шейдеры асинхронно. Это может уменьшить подтормаживания, но также может вызвать графические артефакты. Настройки распаковки текстур (Unswizzle) From ca1fcaca3bc391491111fe951883cb57ac00a61c Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 6 May 2026 03:23:27 +0200 Subject: [PATCH 10/58] [opengl] remove GLAD symbols from builds w/o OpenGL (#3922) removes unused symbols from non-OpenGL builds, notably mac I REMEMBER MAKING THIS PR A WHILE AGO but I have no record of it here, so hell lets redo it Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3922 Reviewed-by: crueter Reviewed-by: MaranBr --- src/video_core/CMakeLists.txt | 5 ++- src/yuzu/CMakeLists.txt | 5 ++- src/yuzu/bootmanager.cpp | 31 +++++++++++++------ src/yuzu_cmd/CMakeLists.txt | 16 ++++++++-- .../emu_window/emu_window_sdl2_gl.cpp | 16 ++++------ src/yuzu_cmd/yuzu.cpp | 7 +++++ 6 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 25eb7846b4..be53b71393 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -323,7 +323,10 @@ if (ENABLE_OPENGL) endif() target_link_libraries(video_core PUBLIC common core) -target_link_libraries(video_core PUBLIC glad shader_recompiler stb bc_decoder gpu_logging) +target_link_libraries(video_core PUBLIC shader_recompiler stb bc_decoder gpu_logging) +if (ENABLE_OPENGL) + target_link_libraries(video_core PUBLIC glad) +endif() if (YUZU_USE_EXTERNAL_FFMPEG) add_dependencies(video_core ffmpeg-build) diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 3adce1dd8b..ff0312660b 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -411,8 +411,11 @@ endif() target_link_libraries(yuzu PRIVATE nlohmann_json::nlohmann_json) target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core qt_common) -target_link_libraries(yuzu PRIVATE Boost::headers glad Qt6::Widgets Qt6::Charts Qt6::Concurrent) +target_link_libraries(yuzu PRIVATE Boost::headers Qt6::Widgets Qt6::Charts Qt6::Concurrent) target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) +if (ENABLE_OPENGL) + target_link_libraries(yuzu PRIVATE glad) +endif() if (UNIX AND NOT APPLE) target_link_libraries(yuzu PRIVATE Qt6::DBus) diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 0c0ce6e90c..2408ef265f 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -8,7 +8,10 @@ #include #include #include + +#ifdef HAS_OPENGL #include +#endif #include #include "common/settings_enums.h" @@ -1039,11 +1042,12 @@ void GRenderWindow::InitializeNull() { } bool GRenderWindow::LoadOpenGL() { +#ifdef HAS_OPENGL auto context = CreateSharedContext(); auto scope = context->Acquire(); if (!gladLoadGL()) { - QMessageBox::warning( - this, tr("Error while initializing OpenGL!"), + QtCommon::Frontend::Warning( + tr("Error while initializing OpenGL!"), tr("Your GPU may not support OpenGL, or you do not have the latest graphics driver.")); return false; } @@ -1052,15 +1056,16 @@ bool GRenderWindow::LoadOpenGL() { const QString renderer = QString::fromUtf8(reinterpret_cast(glGetString(GL_RENDERER))); if (!GLAD_GL_VERSION_4_6) { - QMessageBox::warning(this, tr("Error while initializing OpenGL 4.6!"), - tr("Your GPU may not support OpenGL 4.6, or you do not have the " - "latest graphics driver.

GL Renderer:
%1") - .arg(renderer)); + QtCommon::Frontend::Warning( + tr("Error while initializing OpenGL 4.6!"), + tr("Your GPU may not support OpenGL 4.6, or you do not have the " + "latest graphics driver.

GL Renderer:
%1") + .arg(renderer)); return false; } if (QStringList missing_ext = GetUnsupportedGLExtensions(); !missing_ext.empty()) { - QMessageBox::warning( - this, tr("Error while initializing OpenGL!"), + QtCommon::Frontend::Warning( + tr("Error while initializing OpenGL!"), tr("Your GPU may not support one or more required OpenGL extensions. Please ensure you " "have the latest graphics driver.

GL Renderer:
%1

Unsupported " "extensions:
%2") @@ -1069,10 +1074,17 @@ bool GRenderWindow::LoadOpenGL() { // Non fatal } return true; +#else + QtCommon::Frontend::Warning( + tr("Error while initializing OpenGL!"), + tr("This build doesn't have OpenGL support.")); + return false; +#endif } QStringList GRenderWindow::GetUnsupportedGLExtensions() const { - QStringList missing_ext; + QStringList missing_ext{}; +#ifdef HAS_OPENGL // Extensions required to support some texture formats. if (!GLAD_GL_EXT_texture_compression_s3tc) missing_ext.append(QStringLiteral("EXT_texture_compression_s3tc")); @@ -1082,6 +1094,7 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const { LOG_ERROR(Frontend, "GPU does not support all required extensions"); for (const QString& ext : missing_ext) LOG_ERROR(Frontend, "Unsupported GL extension: {}", ext.toStdString()); +#endif return missing_ext; } diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt index 8f92525ad6..35df53f381 100644 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt @@ -15,11 +15,18 @@ function(create_resource file output filename) file(WRITE "${PROJECT_BINARY_DIR}/dist/${output}" "const unsigned char ${filename}[] = {${filedata}};\nconst unsigned ${filename}_size = sizeof(${filename});\n") endfunction() +if (ENABLE_OPENGL) + list(APPEND OPENGL_SOURCES + emu_window/emu_window_sdl2_gl.cpp + emu_window/emu_window_sdl2_gl.h + ) +else() + set(OPENGL_SOURCES "") +endif() + add_executable(yuzu-cmd emu_window/emu_window_sdl2.cpp emu_window/emu_window_sdl2.h - emu_window/emu_window_sdl2_gl.cpp - emu_window/emu_window_sdl2_gl.h emu_window/emu_window_sdl2_null.cpp emu_window/emu_window_sdl2_null.h emu_window/emu_window_sdl2_vk.cpp @@ -28,10 +35,13 @@ add_executable(yuzu-cmd sdl_config.h yuzu.cpp yuzu.rc + ${OPENGL_SOURCES} ) target_link_libraries(yuzu-cmd PRIVATE common core input_common frontend_common video_core) -target_link_libraries(yuzu-cmd PRIVATE glad) +if (ENABLE_OPENGL) + target_link_libraries(yuzu-cmd PRIVATE glad) +endif() if (MSVC) target_link_libraries(yuzu-cmd PRIVATE getopt) endif() diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 94a6a69776..448c902131 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -59,20 +59,16 @@ private: }; bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { - std::vector unsupported_ext; - + std::vector unsupported_ext{}; +#ifdef HAS_OPENGL // Extensions required to support some texture formats. - if (!GLAD_GL_EXT_texture_compression_s3tc) { + if (!GLAD_GL_EXT_texture_compression_s3tc) unsupported_ext.push_back("EXT_texture_compression_s3tc"); - } - if (!GLAD_GL_ARB_texture_compression_rgtc) { + if (!GLAD_GL_ARB_texture_compression_rgtc) unsupported_ext.push_back("ARB_texture_compression_rgtc"); - } - - for (const auto& extension : unsupported_ext) { + for (const auto& extension : unsupported_ext) LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", extension); - } - +#endif return unsupported_ext.empty(); } diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 8e518d816c..54cc832bf2 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -31,7 +31,9 @@ #include "sdl_config.h" #include "video_core/renderer_base.h" #include "yuzu_cmd/emu_window/emu_window_sdl2.h" +#ifdef HAS_OPENGL #include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h" +#endif #include "yuzu_cmd/emu_window/emu_window_sdl2_null.h" #include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" @@ -349,17 +351,22 @@ int main(int argc, char** argv) { std::unique_ptr emu_window; switch (Settings::values.renderer_backend.GetValue()) { +#ifdef HAS_OPENGL case Settings::RendererBackend::OpenGL_GLSL: case Settings::RendererBackend::OpenGL_GLASM: case Settings::RendererBackend::OpenGL_SPIRV: emu_window = std::make_unique(&input_subsystem, system, fullscreen); break; +#endif case Settings::RendererBackend::Vulkan: emu_window = std::make_unique(&input_subsystem, system, fullscreen); break; case Settings::RendererBackend::Null: emu_window = std::make_unique(&input_subsystem, system, fullscreen); break; + default: + LOG_CRITICAL(Frontend, "Invalid renderer backend"); + return -1; } #ifdef _WIN32 From 8b9a841d994e395b9de144a0159df75d53710551 Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 6 May 2026 03:27:51 +0200 Subject: [PATCH 11/58] [desktop] Fix QtCommon missing header in bootmanager.cpp (#3931) Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3931 --- src/yuzu/bootmanager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 2408ef265f..dd55034e4e 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -15,7 +15,10 @@ #include #include "common/settings_enums.h" + #include "qt_common/config/uisettings.h" +#include "qt_common/abstract/frontend.h" + #if YUZU_USE_QT_MULTIMEDIA #include #include From 86eae5cc4173d46b0ae72fc4fe741a339e263c89 Mon Sep 17 00:00:00 2001 From: PavelBARABANOV Date: Wed, 6 May 2026 04:20:55 +0200 Subject: [PATCH 12/58] [core] Fix qlaunch crash on second launch (#3930) partial revert [08232ce642](https://git.eden-emu.dev/eden-emu/eden/commit/08232ce64275eaf388eba7005f4dae28fc18a0b7) Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3930 Reviewed-by: Lizzie Reviewed-by: MaranBr --- src/core/core.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 2c8cbe21bb..e730b808e0 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -415,7 +415,6 @@ struct System::Impl { cpu_manager.Shutdown(); debugger.reset(); kernel.Shutdown(); - device_memory.reset(); stop_event = {}; Network::RestartSocketOperations(); From 65beea7c734ef6a4e72ab9be89f213d681654743 Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 6 May 2026 16:50:38 +0200 Subject: [PATCH 13/58] [docs] Clean up debug and development docs + fix mdlint (#3936) Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3936 Reviewed-by: Lizzie Reviewed-by: MaranBr --- docs/Debug.md | 51 +++++++++-------- docs/Development.md | 135 +++++--------------------------------------- 2 files changed, 41 insertions(+), 145 deletions(-) diff --git a/docs/Debug.md b/docs/Debug.md index f384918fe2..335806d52b 100644 --- a/docs/Debug.md +++ b/docs/Debug.md @@ -9,6 +9,7 @@ When reporting issues or finding bugs, we often need backtraces, debug logs, or If your bug is related to a graphical issue--e.g. mismatched colors, vertex explosions, flickering, etc.--then you are required to include graphical debugging logs in your issue reports. Graphics Debugging is found in General -> Debug on desktop, and Advanced Settings -> Debug on Android. Android users are all set; however, desktop users may need to install the Vulkan Validation Layers: + - Windows: Install the [Vulkan SDK](https://vulkan.lunarg.com/sdk/home) - Linux, BSD, etc: Install `vulkan-validation-layers`, `vulkan-layers`, or similar from your package manager. It should be located in e.g. `/usr/lib64/libVkLayer_khronos_validation.so` @@ -30,15 +31,16 @@ Ignoring SIGSEGV when debugging in host: ### gdb 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` -Run `./build/bin/eden-cli -c -d -g ` -Or `Enable GDB Stub` at General > Debug, then hook up an aarch64-gdb: -* `target remote localhost:6543` +- On Arch: + - `sudo pacman -Syu aarch64-linux-gnu-gdb` +- On Gentoo: + - `sudo emerge --ask crossdev` + - `sudo crossdev -t aarch64-unknown-linux-gnu --ex-gdb` + +Run `./build/bin/eden-cli -c -d -g `, 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` @@ -69,26 +71,27 @@ For more information type `info gdb` and read [the man page](https://man7.org/li ## Simple checklist for debugging black screens using Renderdoc -Renderdoc is a free, cross platform, multi-graphics API debugger. It is an invaluable tool for diagnosing issues with graphics applications, and includes support for Vulkan. Get it [here](https://renderdoc.org). +Renderdoc is a free, cross platform, multi-graphics API debugger. It is an invaluable tool for diagnosing issues with graphics applications, and includes support for Vulkan. Get it at [renderdoc.org](https://renderdoc.org). Before using renderdoc to diagnose issues, it is always good to make sure there are no validation errors. Any errors means the behavior of the application is undefined. That said, renderdoc can help debug validation errors if you do have them. When debugging a black screen, there are many ways the application could have setup Vulkan wrong. Here is a short checklist of items to look at to make sure are appropriate: -* Draw call counts are correct (aka not zero, or if rendering many triangles, not 3) -* Vertex buffers are bound -* vertex attributes are correct - Make sure the size & offset of each attribute matches what should it should be -* Any bound push constants and descriptors have the right data - including: - * Matrices have correct values - double check the model, view, & projection matrices are uploaded correctly -* Pipeline state is correct - * viewport range is correct - x,y are 0,0; width & height are screen dimensions, minDepth is 0, maxDepth is 1, NDCDepthRange is 0,1 - * Fill mode matches expected - usually solid - * Culling mode makes sense - commonly back or none - * The winding direction is correct - typically CCW (counter clockwise) - * Scissor region is correct - usually same as viewport's x,y,width, &height -* Blend state is correct -* Depth state is correct - typically enabled with Function set to Less than or Equal -* Swapchain images are bound when rendering to the swapchain -* Image being rendered to is the same as the one being presented when rendering to the swapchain + +- Draw call counts are correct (aka not zero, or if rendering many triangles, not 3) +- Vertex buffers are bound +- vertex attributes are correct - Make sure the size & offset of each attribute matches what should it should be +- Any bound push constants and descriptors have the right data - including: + - Matrices have correct values - double check the model, view, & projection matrices are uploaded correctly +- Pipeline state is correct + - viewport range is correct - x,y are 0,0; width & height are screen dimensions, minDepth is 0, maxDepth is 1, NDCDepthRange is 0,1 + - Fill mode matches expected - usually solid + - Culling mode makes sense - commonly back or none + - The winding direction is correct - typically CCW (counter clockwise) + - Scissor region is correct - usually same as viewport's x,y,width, &height +- Blend state is correct +- Depth state is correct - typically enabled with Function set to Less than or Equal +- Swapchain images are bound when rendering to the swapchain +- Image being rendered to is the same as the one being presented when rendering to the swapchain Alternatively, a [RenderDoc Extension](https://github.com/baldurk/renderdoc-contrib/tree/main/baldurk/whereismydraw) ([Archive](https://web.archive.org/web/20250000000000*/https://github.com/baldurk/renderdoc-contrib/tree/main/baldurk/whereismydraw)) exists which automates doing a lot of these manual steps. diff --git a/docs/Development.md b/docs/Development.md index eb9f4159b5..0c7543c156 100644 --- a/docs/Development.md +++ b/docs/Development.md @@ -1,9 +1,11 @@ # Development guidelines ## License Headers + All commits must have proper license header accreditation. You can easily add all necessary license headers by running: + ```sh git fetch origin master:master .ci/license-header.sh -u -c @@ -11,6 +13,7 @@ git push ``` Alternatively, you may omit `-c` and do an amend commit: + ```sh git fetch origin master:master .ci/license-header.sh @@ -22,8 +25,10 @@ If the work is licensed/vendored from other people or projects, you may omit the For more information on the license header script, run `.ci/license-header.sh -h`. ## Pull Requests + Pull requests are only to be merged by core developers when properly tested and discussions conclude on Discord or other communication channels. Labels are recommended but not required. However, all PRs MUST be namespaced and optionally typed: -``` + +```txt [cmake] refactor: CPM over submodules [desktop] feat: implement firmware install from ZIP [hle] stub fw20 functions @@ -34,7 +39,7 @@ Pull requests are only to be merged by core developers when properly tested and - The level of namespacing is generally left to the committer's choice. - However, we never recommend going more than two levels *except* in `hle`, in which case you may go as many as four levels depending on the specificity of your changes. - Ocassionally, up to two additional namespaces may be provided for more clarity. - * Changes that affect the entire project (sans CMake changes) should be namespaced as `meta`. + - Changes that affect the entire project (sans CMake changes) should be namespaced as `meta`. - Maintainers are permitted to change namespaces at will. - Commits within PRs are not required to be namespaced, but it is highly recommended. @@ -50,6 +55,7 @@ When adding new settings, use `tr("Setting:")` if the setting is meant to be a f - Try to not write "slow/fast" options unless it clearly degrades/increases performance for a given case, as most options may modify behaviour that result in different metrics accross different systems. If for example the option is an "accuracy" option, writing "High" is sufficient to imply "Slow". No need to write "High (Slow)". Some examples: + - "[...] negatively affecting image quality", "[...] degrading image quality": Same wording but with less filler. - "[...] this may cause some glitches or crashes in some games", "[...] this may cause soft-crashes": Crashes implies there may be glitches (as crashes are technically a form of a fatal glitch). The entire sentence is structured as "may cause [...] on some games", which is redundant, because "may cause [...] in games" has the same semantic meaning ("may" is a chance that it will occur on "some" given set). - "FIFO Relaxed is similar to FIFO [...]", "FIFO Relaxed [...]": The name already implies similarity. @@ -57,13 +63,16 @@ Some examples: - "[...] it can [...] in some cases", "[...] it can [...]": Implied probability. Before adding a new setting, consider: + - Does the piece of code that the setting pertains to, make a significant difference if it's on/off? - Can it be auto-detected? # IDE setup ## VSCode + Copy this to `.vscode/settings.json`, get CMake tools and it should be ready to build: + ```json { "editor.tabSize": 4, @@ -83,6 +92,7 @@ You may additionally need the `Qt Extension Pack` extension if building Qt. # Build speedup If you have an HDD, use ramdisk (build in RAM), approximatedly you need 4GB for a full build with debug symbols: + ```sh mkdir /tmp/ramdisk chmod 777 /tmp/ramdisk @@ -96,128 +106,11 @@ umount /tmp/ramdisk # Assets and large files A general rule of thumb, before uploading files: + - PNG files: Use [optipng](https://web.archive.org/web/20240325055059/https://optipng.sourceforge.net/). - SVG files: Use [svgo](https://github.com/svg/svgo). May not be used but worth mentioning nonethless: + - OGG files: Use [OptiVorbis](https://github.com/OptiVorbis/OptiVorbis). - Video files: Use ffmpeg, preferably re-encode as AV1. - -# Bisecting older commits - -Since going into the past can be tricky (especially due to the dependencies from the project being lost thru time). This should "restore" the URLs for the respective submodules. - -```sh -#!/bin/sh -e -cat > .gitmodules < externals/dynarmic/src/dynarmic/common/x64_disassemble.cpp < -#include -#include -namespace Dynarmic::Common { -void DumpDisassembledX64(const void* ptr, size_t size) {} -std::vector DisassembleX64(const void* ptr, size_t size) { return {}; } -} -EOF -``` - -If having issues with older artifacts, then run `rm -r externals/dynarmic/build externals/dynarmic/externals externals/nx_tzdb/tzdb_to_nx/externals externals/sirit/externals`. - -Configuring CMake with `-DSIRIT_USE_SYSTEM_SPIRV_HEADERS=1 -DCMAKE_CXX_FLAGS="-Wno-error" -DCMAKE_C_FLAGS="-Wno-error -Wno-array-parameter -Wno-stringop-overflow"` is also recommended. From 37026c8aaa9e1ce01026c2aa69b4b8af5842ec5a Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 6 May 2026 18:49:44 +0200 Subject: [PATCH 14/58] [ci] Remove dead scripts (#3935) These are horrifically outdated. Just use CMake Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3935 Reviewed-by: Lizzie Reviewed-by: MaranBr --- .ci/linux/build.sh | 116 ------------------- .ci/linux/eden.dwfsprof | 250 ---------------------------------------- .ci/linux/package.sh | 153 ------------------------ .ci/windows/build.sh | 51 -------- .ci/windows/package.sh | 18 --- 5 files changed, 588 deletions(-) delete mode 100755 .ci/linux/build.sh delete mode 100644 .ci/linux/eden.dwfsprof delete mode 100755 .ci/linux/package.sh delete mode 100755 .ci/windows/build.sh delete mode 100644 .ci/windows/package.sh diff --git a/.ci/linux/build.sh b/.ci/linux/build.sh deleted file mode 100755 index 2a0a7e58b1..0000000000 --- a/.ci/linux/build.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash -e - -# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - -case "$1" in -amd64 | "") - echo "Making amd64-v3 optimized build of Eden" - ARCH="amd64_v3" - ARCH_FLAGS="-march=x86-64-v3" - export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=v3) - ;; -steamdeck | zen2) - echo "Making Steam Deck (Zen 2) optimized build of Eden" - ARCH="steamdeck" - ARCH_FLAGS="-march=znver2 -mtune=znver2" - export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=zen2 -DYUZU_SYSTEM_PROFILE=steamdeck) - ;; -rog-ally | allyx | zen4) - echo "Making ROG Ally X (Zen 4) optimized build of Eden" - ARCH="rog-ally-x" - ARCH_FLAGS="-march=znver4 -mtune=znver4" - export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=zen2 -DYUZU_SYSTEM_PROFILE=steamdeck) - ;; -legacy) - echo "Making amd64 generic build of Eden" - ARCH=amd64 - ARCH_FLAGS="-march=x86-64 -mtune=generic" - export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=generic) - ;; -aarch64) - echo "Making armv8-a build of Eden" - ARCH=aarch64 - ARCH_FLAGS="-march=armv8-a -mtune=generic -w" - export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=generic) - ;; -armv9) - echo "Making armv9-a build of Eden" - ARCH=armv9 - ARCH_FLAGS="-march=armv9-a -mtune=generic -w" - export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=armv9) - ;; -native) - echo "Making native build of Eden" - ARCH="$(uname -m)" - ARCH_FLAGS="-march=native -mtune=native" - export EXTRA_CMAKE_FLAGS=(-DYUZU_BUILD_PRESET=native) - ;; -*) - echo "Invalid target $1 specified, must be one of native, amd64, steamdeck, zen2, allyx, rog-ally, zen4, legacy, aarch64, armv9" - exit 1 - ;; -esac - -export ARCH_FLAGS="$ARCH_FLAGS -O3" - -if [ -z "$NPROC" ]; then - NPROC="$(nproc)" -fi - -if [ "$1" != "" ]; then shift; fi - -if [ "$TARGET" = "appimage" ]; then - export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DCMAKE_INSTALL_PREFIX=/usr -DYUZU_ROOM=ON -DYUZU_ROOM_STANDALONE=OFF -DYUZU_CMD=OFF) -else - # For the linux-fresh verification target, verify compilation without PCH as well. - export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DYUZU_USE_PRECOMPILED_HEADERS=OFF) -fi - - -if [ "$DEVEL" != "true" ]; then - export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DENABLE_UPDATE_CHECKER=ON) -fi - -if [ "$USE_WEBENGINE" = "true" ]; then - WEBENGINE=ON -else - WEBENGINE=OFF -fi - -if [ "$USE_MULTIMEDIA" = "false" ]; then - MULTIMEDIA=OFF -else - MULTIMEDIA=ON -fi - -if [ -z "$BUILD_TYPE" ]; then - export BUILD_TYPE="Release" -fi - -export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" $@) - -mkdir -p build && cd build -cmake .. -G Ninja \ - -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ - -DENABLE_QT_TRANSLATION=ON \ - -DUSE_DISCORD_PRESENCE=ON \ - -DCMAKE_CXX_FLAGS="$ARCH_FLAGS" \ - -DCMAKE_C_FLAGS="$ARCH_FLAGS" \ - -DYUZU_USE_BUNDLED_QT=OFF \ - -DYUZU_USE_BUNDLED_SDL2=OFF \ - -DYUZU_USE_EXTERNAL_SDL2=ON \ - -DYUZU_TESTS=OFF \ - -DYUZU_USE_QT_MULTIMEDIA=$MULTIMEDIA \ - -DYUZU_USE_QT_WEB_ENGINE=$WEBENGINE \ - -DYUZU_USE_FASTER_LD=ON \ - -DENABLE_LTO=ON \ - "${EXTRA_CMAKE_FLAGS[@]}" - -ninja -j${NPROC} - -if [ -d "bin/Release" ]; then - strip -s bin/Release/* -else - strip -s bin/* -fi diff --git a/.ci/linux/eden.dwfsprof b/.ci/linux/eden.dwfsprof deleted file mode 100644 index 9a3bee6f14..0000000000 --- a/.ci/linux/eden.dwfsprof +++ /dev/null @@ -1,250 +0,0 @@ -AppRun -eden.desktop -dev.eden_emu.eden.desktop -shared/bin/eden -shared/lib/lib.path -shared/lib/ld-linux-x86-64.so.2 -shared/lib/libQt6Widgets.so.6.4.2 -shared/lib/libQt6DBus.so.6.4.2 -shared/lib/libudev.so.1.7.5 -shared/lib/libbrotlienc.so.1.0.9 -shared/lib/libbrotlidec.so.1.0.9 -shared/lib/libssl.so.3 -shared/lib/libcrypto.so.3 -shared/lib/libavcodec.so.59.37.100 -shared/lib/libavutil.so.57.28.100 -shared/lib/libQt6Gui.so.6.4.2 -shared/lib/libQt6Core.so.6.4.2 -shared/lib/libstdc++.so.6.0.30 -shared/lib/libm.so.6 -shared/lib/libgcc_s.so.1 -shared/lib/libc.so.6 -shared/lib/libdbus-1.so.3.32.4 -shared/lib/libbrotlicommon.so.1.0.9 -shared/lib/libswresample.so.4.7.100 -shared/lib/libvpx.so.7.1.0 -shared/lib/libwebpmux.so.3.0.10 -shared/lib/libwebp.so.7.1.5 -shared/lib/liblzma.so.5.4.1 -shared/lib/libdav1d.so.6.6.0 -shared/lib/librsvg-2.so.2.48.0 -shared/lib/libgobject-2.0.so.0.7400.6 -shared/lib/libglib-2.0.so.0.7400.6 -shared/lib/libcairo.so.2.11600.0 -shared/lib/libzvbi.so.0.13.2 -shared/lib/libz.so.1.2.13 -shared/lib/libsnappy.so.1.1.9 -shared/lib/libaom.so.3.6.0 -shared/lib/libcodec2.so.1.0 -shared/lib/libgsm.so.1.0.19 -shared/lib/libjxl.so.0.7.0 -shared/lib/libjxl_threads.so.0.7.0 -shared/lib/libmp3lame.so.0.0.0 -shared/lib/libopenjp2.so.2.5.0 -shared/lib/libopus.so.0.8.0 -shared/lib/librav1e.so.0.5.1 -shared/lib/libshine.so.3.0.1 -shared/lib/libspeex.so.1.5.2 -shared/lib/libSvtAv1Enc.so.1.4.1 -shared/lib/libtheoraenc.so.1.1.2 -shared/lib/libtheoradec.so.1.1.4 -shared/lib/libtwolame.so.0.0.0 -shared/lib/libvorbis.so.0.4.9 -shared/lib/libvorbisenc.so.2.0.12 -shared/lib/libx264.so.164 -shared/lib/libx265.so.199 -shared/lib/libxvidcore.so.4.3 -shared/lib/libva.so.2.1700.0 -shared/lib/libmfx.so.1.35 -shared/lib/libva-drm.so.2.1700.0 -shared/lib/libva-x11.so.2.1700.0 -shared/lib/libvdpau.so.1.0.0 -shared/lib/libX11.so.6.4.0 -shared/lib/libdrm.so.2.4.0 -shared/lib/libOpenCL.so.1.0.0 -shared/lib/libEGL.so.1.1.0 -shared/lib/libfontconfig.so.1.12.0 -shared/lib/libxkbcommon.so.0.0.0 -shared/lib/libGLX.so.0.0.0 -shared/lib/libOpenGL.so.0.0.0 -shared/lib/libpng16.so.16.39.0 -shared/lib/libharfbuzz.so.0.60000.0 -shared/lib/libmd4c.so.0.4.8 -shared/lib/libfreetype.so.6.18.3 -shared/lib/libicui18n.so.72.1 -shared/lib/libicuuc.so.72.1 -shared/lib/libdouble-conversion.so.3.1 -shared/lib/libb2.so.1.0.4 -shared/lib/libpcre2-16.so.0.11.2 -shared/lib/libzstd.so.1.5.4 -shared/lib/libsystemd.so.0.35.0 -shared/lib/libsoxr.so.0.1.2 -shared/lib/libcairo-gobject.so.2.11600.0 -shared/lib/libgdk_pixbuf-2.0.so.0.4200.10 -shared/lib/libgio-2.0.so.0.7400.6 -shared/lib/libxml2.so.2.9.14 -shared/lib/libpangocairo-1.0.so.0.5000.12 -shared/lib/libpango-1.0.so.0.5000.12 -shared/lib/libffi.so.8.1.2 -shared/lib/libpcre2-8.so.0.11.2 -shared/lib/libpixman-1.so.0.42.2 -shared/lib/libxcb-shm.so.0.0.0 -shared/lib/libxcb.so.1.1.0 -shared/lib/libxcb-render.so.0.0.0 -shared/lib/libXrender.so.1.3.0 -shared/lib/libXext.so.6.4.0 -shared/lib/libhwy.so.1.0.3 -shared/lib/liblcms2.so.2.0.14 -shared/lib/libogg.so.0.8.5 -shared/lib/libnuma.so.1.0.0 -shared/lib/libpthread.so.0 -shared/lib/libXfixes.so.3.1.0 -shared/lib/libX11-xcb.so.1.0.0 -shared/lib/libxcb-dri3.so.0.1.0 -shared/lib/libGLdispatch.so.0.0.0 -shared/lib/libexpat.so.1.8.10 -shared/lib/libgraphite2.so.3.2.1 -shared/lib/libicudata.so.72.1 -shared/lib/libgomp.so.1.0.0 -shared/lib/libcap.so.2.66 -shared/lib/libgcrypt.so.20.4.1 -shared/lib/liblz4.so.1.9.4 -shared/lib/libgmodule-2.0.so.0.7400.6 -shared/lib/libjpeg.so.62.3.0 -shared/lib/libmount.so.1.1.0 -shared/lib/libselinux.so.1 -shared/lib/libpangoft2-1.0.so.0.5000.12 -shared/lib/libfribidi.so.0.4.0 -shared/lib/libthai.so.0.3.1 -shared/lib/libXau.so.6.0.0 -shared/lib/libXdmcp.so.6.0.0 -shared/lib/libgpg-error.so.0.33.1 -shared/lib/libblkid.so.1.1.0 -shared/lib/libdatrie.so.1.4.0 -shared/lib/libbsd.so.0.11.7 -shared/lib/libmd.so.0.0.5 -shared/lib/libvulkan.so.1.3.239 -share/vulkan/icd.d/intel_hasvk_icd.x86_64.json -shared/lib/libvulkan_intel_hasvk.so -shared/lib/libwayland-client.so.0.21.0 -shared/lib/libxcb-present.so.0.0.0 -shared/lib/libxcb-xfixes.so.0.0.0 -shared/lib/libxcb-sync.so.1.0.0 -shared/lib/libxcb-randr.so.0.1.0 -shared/lib/libxshmfence.so.1.0.0 -share/vulkan/icd.d/intel_icd.x86_64.json -shared/lib/libvulkan_intel.so -share/vulkan/icd.d/lvp_icd.x86_64.json -shared/lib/libvulkan_lvp.so -shared/lib/libLLVM-15.so.1 -shared/lib/libedit.so.2.0.70 -shared/lib/libz3.so.4 -shared/lib/libtinfo.so.6.4 -share/vulkan/icd.d/radeon_icd.x86_64.json -shared/lib/libvulkan_radeon.so -shared/lib/libdrm_amdgpu.so.1.0.0 -shared/lib/libelf-0.188.so -shared/lib/libVkLayer_MESA_device_select.so -bin/qt.conf -shared/lib/qt6/plugins/platforms/libqeglfs.so -shared/lib/qt6/plugins/platforms/libqlinuxfb.so -shared/lib/qt6/plugins/platforms/libqminimal.so -shared/lib/qt6/plugins/platforms/libqminimalegl.so -shared/lib/qt6/plugins/platforms/libqoffscreen.so -shared/lib/qt6/plugins/platforms/libqvkkhrdisplay.so -shared/lib/qt6/plugins/platforms/libqvnc.so -shared/lib/qt6/plugins/platforms/libqwayland-egl.so -shared/lib/qt6/plugins/platforms/libqwayland-generic.so -shared/lib/qt6/plugins/platforms/libqxcb.so -shared/lib/libQt6WaylandClient.so.6.4.2 -shared/lib/libwayland-cursor.so.0.21.0 -shared/lib/qt6/plugins/platformthemes/libqgtk3.so -shared/lib/libgtk-3.so.0.2406.32 -shared/lib/libgdk-3.so.0.2406.32 -shared/lib/libatk-1.0.so.0.24609.1 -shared/lib/libepoxy.so.0.0.0 -shared/lib/libXi.so.6.1.0 -shared/lib/libatk-bridge-2.0.so.0.0.0 -shared/lib/libwayland-egl.so.1.21.0 -shared/lib/libXcursor.so.1.0.2 -shared/lib/libXdamage.so.1.1.0 -shared/lib/libXcomposite.so.1.0.0 -shared/lib/libXrandr.so.2.2.0 -shared/lib/libXinerama.so.1.0.0 -shared/lib/libdl.so.2 -shared/lib/libatspi.so.0.0.1 -share/glib-2.0/schemas/gschemas.compiled -shared/lib/gio/modules/giomodule.cache -shared/lib/gio/modules/libdconfsettings.so -shared/lib/gio/modules/libgvfsdbus.so -shared/lib/gvfs/libgvfscommon.so -share/X11/xkb/rules/evdev -share/X11/xkb/keycodes/evdev -share/X11/xkb/keycodes/aliases -share/X11/xkb/types/complete -share/X11/xkb/types/basic -share/X11/xkb/types/mousekeys -share/X11/xkb/types/pc -share/X11/xkb/types/iso9995 -share/X11/xkb/types/level5 -share/X11/xkb/types/extra -share/X11/xkb/types/numpad -share/X11/xkb/compat/complete -share/X11/xkb/compat/basic -share/X11/xkb/compat/ledcaps -share/X11/xkb/compat/lednum -share/X11/xkb/compat/iso9995 -share/X11/xkb/compat/mousekeys -share/X11/xkb/compat/accessx -share/X11/xkb/compat/misc -share/X11/xkb/compat/ledscroll -share/X11/xkb/compat/xfree86 -share/X11/xkb/compat/level5 -share/X11/xkb/compat/caps -share/X11/xkb/symbols/pc -share/X11/xkb/symbols/srvr_ctrl -share/X11/xkb/symbols/keypad -share/X11/xkb/symbols/altwin -share/X11/xkb/symbols/us -share/X11/xkb/symbols/inet -shared/lib/qt6/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.so -shared/lib/qt6/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so -shared/lib/qt6/plugins/iconengines/libqsvgicon.so -shared/lib/qt6/plugins/imageformats/libqgif.so -shared/lib/qt6/plugins/imageformats/libqico.so -shared/lib/qt6/plugins/imageformats/libqjpeg.so -shared/lib/qt6/plugins/imageformats/libqsvg.so -shared/lib/libQt6Svg.so.6.4.2 -etc/fonts/fonts.conf -shared/lib/qt6/plugins/wayland-shell-integration/libfullscreen-shell-v1.so -shared/lib/qt6/plugins/wayland-shell-integration/libivi-shell.so -shared/lib/qt6/plugins/wayland-shell-integration/libqt-shell.so -shared/lib/qt6/plugins/wayland-shell-integration/libwl-shell-plugin.so -shared/lib/qt6/plugins/wayland-shell-integration/libxdg-shell.so -shared/lib/qt6/plugins/wayland-graphics-integration-client/libdmabuf-server.so -shared/lib/qt6/plugins/wayland-graphics-integration-client/libdrm-egl-server.so -shared/lib/qt6/plugins/wayland-graphics-integration-client/libqt-plugin-wayland-egl.so -shared/lib/qt6/plugins/wayland-graphics-integration-client/libshm-emulation-server.so -shared/lib/qt6/plugins/wayland-graphics-integration-client/libvulkan-server.so -shared/lib/libQt6WaylandEglClientHwIntegration.so.6.4.2 -shared/lib/libQt6OpenGL.so.6.4.2 -share/glvnd/egl_vendor.d/50_mesa.json -shared/lib/libEGL_mesa.so.0.0.0 -shared/lib/libgbm.so.1.0.0 -shared/lib/libglapi.so.0.0.0 -shared/lib/libxcb-dri2.so.0.0.0 -shared/lib/libwayland-server.so.0.21.0 -shared/lib/dri/swrast_dri.so -shared/lib/libsensors.so.5.0.0 -shared/lib/libdrm_radeon.so.1.0.1 -shared/lib/libdrm_nouveau.so.2.0.0 -shared/lib/libdrm_intel.so.1.0.0 -shared/lib/libpciaccess.so.0.11.1 -shared/lib/qt6/plugins/wayland-decoration-client/libbradient.so -shared/lib/gtk-3.0/modules/libcanberra-gtk3-module.so -shared/lib/libcanberra-gtk3.so.0.1.9 -shared/lib/libcanberra.so.0.2.5 -shared/lib/libvorbisfile.so.3.3.8 -shared/lib/libtdb.so.1.4.8 -shared/lib/libltdl.so.7.3.2 -shared/lib/libXss.so.1.0.0 diff --git a/.ci/linux/package.sh b/.ci/linux/package.sh deleted file mode 100755 index 838476097a..0000000000 --- a/.ci/linux/package.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/bin/sh -e - -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - -# This script assumes you're in the source directory - -export APPIMAGE_EXTRACT_AND_RUN=1 -export BASE_ARCH="$(uname -m)" - -SHARUN="https://github.com/VHSgunzo/sharun/releases/latest/download/sharun-${BASE_ARCH}-aio" -URUNTIME="https://github.com/VHSgunzo/uruntime/releases/latest/download/uruntime-appimage-dwarfs-${BASE_ARCH}" - -case "$1" in - amd64|"") - echo "Packaging amd64-v3 optimized build of Eden" - ARCH="amd64_v3" - ;; - steamdeck|zen2) - echo "Packaging Steam Deck (Zen 2) optimized build of Eden" - ARCH="steamdeck" - ;; - rog-ally|allyx|zen4) - echo "Packaging ROG Ally X (Zen 4) optimized build of Eden" - ARCH="rog-ally-x" - ;; - legacy) - echo "Packaging amd64 generic build of Eden" - ARCH=amd64 - ;; - aarch64) - echo "Packaging armv8-a build of Eden" - ARCH=aarch64 - ;; - armv9) - echo "Packaging armv9-a build of Eden" - ARCH=armv9 - ;; - native) - echo "Packaging native build of Eden" - ARCH="$BASE_ARCH" - ;; - -esac - -export BUILDDIR="$2" - -if [ "$BUILDDIR" = '' ] -then - BUILDDIR=build -fi - -EDEN_TAG=$(git describe --tags --abbrev=0) -echo "Making \"$EDEN_TAG\" build" -# git checkout "$EDEN_TAG" -VERSION="$(echo "$EDEN_TAG")" - -# NOW MAKE APPIMAGE -mkdir -p ./AppDir -cd ./AppDir - -cp ../dist/dev.eden_emu.eden.desktop . -cp ../dist/dev.eden_emu.eden.svg . - -ln -sf ./dev.eden_emu.eden.svg ./.DirIcon - -UPINFO='gh-releases-zsync|eden-emulator|Releases|latest|*.AppImage.zsync' - -if [ "$DEVEL" = 'true' ]; then - sed -i 's|Name=Eden|Name=Eden Nightly|' ./dev.eden_emu.eden.desktop - UPINFO="$(echo "$UPINFO" | sed 's|Releases|nightly|')" -fi - -LIBDIR="/usr/lib" - -# Workaround for Gentoo -if [ ! -d "$LIBDIR/qt6" ] -then - LIBDIR="/usr/lib64" -fi - -# Workaround for Debian -if [ ! -d "$LIBDIR/qt6" ] -then - LIBDIR="/usr/lib/${BASE_ARCH}-linux-gnu" -fi - -# Bundle all libs - -wget --retry-connrefused --tries=30 "$SHARUN" -O ./sharun-aio -chmod +x ./sharun-aio -xvfb-run -a ./sharun-aio l -p -v -e -s -k \ - ../$BUILDDIR/bin/eden* \ - $LIBDIR/lib*GL*.so* \ - $LIBDIR/dri/* \ - $LIBDIR/vdpau/* \ - $LIBDIR/libvulkan* \ - $LIBDIR/libXss.so* \ - $LIBDIR/libdecor-0.so* \ - $LIBDIR/libgamemode.so* \ - $LIBDIR/qt6/plugins/audio/* \ - $LIBDIR/qt6/plugins/bearer/* \ - $LIBDIR/qt6/plugins/imageformats/* \ - $LIBDIR/qt6/plugins/iconengines/* \ - $LIBDIR/qt6/plugins/platforms/* \ - $LIBDIR/qt6/plugins/platformthemes/* \ - $LIBDIR/qt6/plugins/platforminputcontexts/* \ - $LIBDIR/qt6/plugins/styles/* \ - $LIBDIR/qt6/plugins/xcbglintegrations/* \ - $LIBDIR/qt6/plugins/wayland-*/* \ - $LIBDIR/pulseaudio/* \ - $LIBDIR/pipewire-0.3/* \ - $LIBDIR/spa-0.2/*/* \ - $LIBDIR/alsa-lib/* - -rm -f ./sharun-aio - -# Prepare sharun -if [ "$ARCH" = 'aarch64' ]; then - # allow the host vulkan to be used for aarch64 given the sad situation - echo 'SHARUN_ALLOW_SYS_VKICD=1' > ./.env -fi - -# Workaround for Gentoo -if [ -d "shared/libproxy" ]; then - cp shared/libproxy/* lib/ -fi - -ln -f ./sharun ./AppRun -./sharun -g - -# turn appdir into appimage -cd .. -wget -q "$URUNTIME" -O ./uruntime -chmod +x ./uruntime - -#Add udpate info to runtime -echo "Adding update information \"$UPINFO\" to runtime..." -./uruntime --appimage-addupdinfo "$UPINFO" - -echo "Generating AppImage..." -./uruntime --appimage-mkdwarfs -f \ - --set-owner 0 --set-group 0 \ - --no-history --no-create-timestamp \ - --categorize=hotness --hotness-list=.ci/linux/eden.dwfsprof \ - --compression zstd:level=22 -S26 -B32 \ - --header uruntime \ - -N 4 \ - -i ./AppDir -o Eden-"$VERSION"-"$ARCH".AppImage - -echo "Generating zsync file..." -zsyncmake *.AppImage -u *.AppImage -echo "All Done!" \ No newline at end of file diff --git a/.ci/windows/build.sh b/.ci/windows/build.sh deleted file mode 100755 index 48cca8eb4d..0000000000 --- a/.ci/windows/build.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash -ex - -# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - -if [ "$COMPILER" == "clang" ] -then - EXTRA_CMAKE_FLAGS+=( - -DCMAKE_CXX_COMPILER=clang-cl - -DCMAKE_C_COMPILER=clang-cl - -DCMAKE_CXX_FLAGS="-O3" - -DCMAKE_C_FLAGS="-O3" - ) - - BUILD_TYPE="RelWithDebInfo" -fi - -[ -z "$WINDEPLOYQT" ] && { echo "WINDEPLOYQT environment variable required."; exit 1; } - -echo $EXTRA_CMAKE_FLAGS - -mkdir -p build && cd build -cmake .. -G Ninja \ - -DCMAKE_BUILD_TYPE="${BUILD_TYPE:-Release}" \ - -DENABLE_QT_TRANSLATION=ON \ - -DUSE_DISCORD_PRESENCE=ON \ - -DYUZU_USE_BUNDLED_SDL2=ON \ - -DBUILD_TESTING=OFF \ - -DYUZU_TESTS=OFF \ - -DDYNARMIC_TESTS=OFF \ - -DYUZU_CMD=OFF \ - -DYUZU_ROOM_STANDALONE=OFF \ - -DYUZU_USE_QT_MULTIMEDIA=${USE_MULTIMEDIA:-false} \ - -DYUZU_USE_QT_WEB_ENGINE=${USE_WEBENGINE:-false} \ - -DENABLE_LTO=ON \ - -DCMAKE_EXE_LINKER_FLAGS=" /LTCG" \ - -DYUZU_USE_BUNDLED_QT=${BUNDLE_QT:-false} \ - -DUSE_CCACHE=${CCACHE:-false} \ - -DENABLE_UPDATE_CHECKER=${DEVEL:-true} \ - "${EXTRA_CMAKE_FLAGS[@]}" \ - "$@" - -ninja - -set +e -rm -f bin/*.pdb -set -e - -$WINDEPLOYQT --release --no-compiler-runtime --no-opengl-sw --no-system-dxc-compiler --no-system-d3d-compiler --dir pkg bin/eden.exe - -cp bin/* pkg diff --git a/.ci/windows/package.sh b/.ci/windows/package.sh deleted file mode 100644 index 2d126dc5be..0000000000 --- a/.ci/windows/package.sh +++ /dev/null @@ -1,18 +0,0 @@ -GITDATE=$(git show -s --date=short --format='%ad' | tr -d "-") -GITREV=$(git show -s --format='%h') - -ZIP_NAME="Eden-Windows-${ARCH}-${GITDATE}-${GITREV}.zip" - -ARTIFACTS_DIR="artifacts" -PKG_DIR="build/pkg" - -mkdir -p "$ARTIFACTS_DIR" - -TMP_DIR=$(mktemp -d) - -cp -r "$PKG_DIR"/* "$TMP_DIR"/ -cp LICENSE* README* "$TMP_DIR"/ - -7z a -tzip "$ARTIFACTS_DIR/$ZIP_NAME" "$TMP_DIR"/* - -rm -rf "$TMP_DIR" \ No newline at end of file From b154a7da3cb657a9e224c29ebda2cba83b16290e Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 6 May 2026 20:23:42 +0200 Subject: [PATCH 15/58] [hle, friend] GetFriendListForViewerV2 STUBBED and update list of functions (#3933) (#3937) Fixes freezes Friend List on firmware 22+ and update list of functions according to data from Switchbrew Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3933 Reviewed-by: crueter Reviewed-by: MaranBr Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3937 --- src/core/hle/service/friend/friend.cpp | 59 +++++++++++++++++--------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index b851de8496..79578956b1 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -53,38 +53,53 @@ public: {20102, nullptr, "GetFriendDetailedInfo"}, {20103, nullptr, "SyncFriendList"}, {20104, &IFriendService::RequestSyncFriendList, "RequestSyncFriendList"}, - {20105, &IFriendService::GetFriendListForViewer, "GetFriendListForViewer"}, - {20110, nullptr, "LoadFriendSetting"}, + {20105, &IFriendService::GetFriendListForViewer, "GetFriendListForViewerV1"}, + {20106, nullptr, "UpdateFriendInfoForViewerV1"}, + {20107, nullptr, "GetFriendDetailedInfoV2"}, // 20.0.0+ + {20108, &IFriendService::GetFriendListForViewer, "GetFriendListForViewerV2"}, // 22.0.0+ + {20109, nullptr, "UpdateFriendInfoForViewerV2"}, // 22.0.0+ + {20110, nullptr, "LoadFriendSettingV1"}, + {20111, nullptr, "LoadFriendSettingV2"}, // 22.0.0+ {20200, &IFriendService::GetReceivedFriendRequestCount, "GetReceivedFriendRequestCount"}, - {20201, nullptr, "GetFriendRequestList"}, + {20201, nullptr, "GetFriendRequestListV1"}, + {20202, nullptr, "GetFriendRequestListV2"}, // 20.0.0+ + {20203, nullptr, "GetFriendRequestReceivedNotificationCount"}, // 22.0.0+ {20300, nullptr, "GetFriendCandidateList"}, {20301, nullptr, "GetNintendoNetworkIdInfo"}, - {20302, nullptr, "GetSnsAccountLinkage"}, - {20303, nullptr, "GetSnsAccountProfile"}, - {20304, nullptr, "GetSnsAccountFriendList"}, - {20400, nullptr, "GetBlockedUserList"}, + {20302, nullptr, "GetSnsAccountLinkage"}, // 5.0.0-19.0.1 + {20303, nullptr, "GetSnsAccountProfile"}, // 5.0.0-19.0.1 + {20304, nullptr, "GetSnsAccountFriendList"}, // 5.0.0-19.0.1 + {20400, nullptr, "GetBlockedUserListV1"}, {20401, nullptr, "SyncBlockedUserList"}, - {20500, nullptr, "GetProfileExtraList"}, + {20402, nullptr, "GetBlockedUserListV2"}, // 20.0.0+ + {20500, nullptr, "GetProfileExtraListV1"}, {20501, nullptr, "GetRelationship"}, + {20502, nullptr, "GetProfileExtraListV2"}, // 19.0.0+ {20600, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV1"}, - {20601, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV2"}, - {20700, nullptr, "GetPlayHistoryList"}, + {20601, &IFriendService::GetUserPresenceView, "GetUserPresenceViewV2"}, // 19.0.0+ + {20700, nullptr, "GetPlayHistoryListV1"}, {20701, &IFriendService::GetPlayHistoryStatistics, "GetPlayHistoryStatistics"}, + {20702, nullptr, "GetPlayHistoryListV2"}, // 19.0.0+ {20800, &IFriendService::LoadUserSetting, "LoadUserSettingV1"}, {20801, nullptr, "SyncUserSetting"}, - {20802, &IFriendService::LoadUserSetting, "LoadUserSettingV2"}, + {20802, &IFriendService::LoadUserSetting, "LoadUserSettingV2"}, // 19.0.0+ {20900, &IFriendService::RequestListSummaryOverlayNotification, "RequestListSummaryOverlayNotification"}, {21000, nullptr, "GetExternalApplicationCatalog"}, - {22000, nullptr, "GetReceivedFriendInvitationList"}, - {22001, nullptr, "GetReceivedFriendInvitationDetailedInfo"}, + {22000, nullptr, "GetReceivedFriendInvitationListV1"}, + {22001, nullptr, "GetReceivedFriendInvitationDetailedInfoV1"}, + {22002, nullptr, "GetReceivedFriendInvitationListV2"}, // 19.0.0+ + {22003, nullptr, "GetReceivedFriendInvitationDetailedInfoV2"}, // 19.0.0+ {22010, &IFriendService::GetReceivedFriendInvitationCountCache, "GetReceivedFriendInvitationCountCache"}, {30100, nullptr, "DropFriendNewlyFlags"}, {30101, nullptr, "DeleteFriend"}, {30110, nullptr, "DropFriendNewlyFlag"}, {30120, nullptr, "ChangeFriendFavoriteFlag"}, {30121, nullptr, "ChangeFriendOnlineNotificationFlag"}, + {30130, nullptr, "SetFriendNote"}, // 22.0.0+ + {30131, nullptr, "RequestUploadPendingNote"}, // 22.0.0+ + {30190, nullptr, "RequestSyncLocalUpdates"}, // 22.0.0+ {30200, nullptr, "SendFriendRequest"}, - {30201, nullptr, "SendFriendRequestWithApplicationInfo"}, + {30201, nullptr, "SendFriendRequestWithApplicationInfoV1"}, {30202, nullptr, "CancelFriendRequest"}, {30203, nullptr, "AcceptFriendRequest"}, {30204, nullptr, "RejectFriendRequest"}, @@ -97,21 +112,27 @@ public: {30215, nullptr, "SendFriendRequestWithExternalApplicationCatalogId"}, {30216, nullptr, "ResendFacedFriendRequest"}, {30217, nullptr, "SendFriendRequestWithNintendoNetworkIdInfo"}, - {30300, nullptr, "GetSnsAccountLinkPageUrl"}, - {30301, nullptr, "UnlinkSnsAccount"}, + {30218, nullptr, "SendFriendRequestWithApplicationInfoV2"}, // 20.0.0+ + {30300, nullptr, "GetSnsAccountLinkPageUrl"}, // 5.0.0-19.0.1 + {30301, nullptr, "UnlinkSnsAccount"}, // 5.0.0-19.0.1 {30400, nullptr, "BlockUser"}, - {30401, nullptr, "BlockUserWithApplicationInfo"}, + {30401, nullptr, "BlockUserWithApplicationInfoV1"}, {30402, nullptr, "UnblockUser"}, - {30500, nullptr, "GetProfileExtraFromFriendCode"}, + {30403, nullptr, "BlockUserWithApplicationInfoV2"}, // 20.0.0+ + {30500, nullptr, "GetProfileExtraFromFriendCodeV1"}, + {30501, nullptr, "GetProfileExtraFromFriendCodeV2"}, // 19.0.0+ {30700, nullptr, "DeletePlayHistory"}, + {30701, nullptr, "AddPlayHistoryWithApplication"}, // 19.0.0+ {30810, nullptr, "ChangePresencePermission"}, {30811, nullptr, "ChangeFriendRequestReception"}, {30812, nullptr, "ChangePlayLogPermission"}, {30820, nullptr, "IssueFriendCode"}, {30830, nullptr, "ClearPlayLog"}, - {30900, nullptr, "SendFriendInvitation"}, + {30900, nullptr, "SendFriendInvitationV1"}, + {30901, nullptr, "SendFriendInvitationV2"}, // 19.0.0+ {30910, nullptr, "ReadFriendInvitation"}, {30911, nullptr, "ReadAllFriendInvitations"}, + {31000, nullptr, "OpenUser"}, // 19.0.0+ {40100, nullptr, "DeleteFriendListCache"}, {40400, nullptr, "DeleteBlockedUserListCache"}, {49900, nullptr, "DeleteNetworkServiceAccountCache"}, From bf115ef5a74977f795e54d2aa2cb1270950e50a2 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 7 May 2026 15:58:17 +0200 Subject: [PATCH 16/58] [cmake] fix & allow FFmpeg cross compilations (#2973) Should allow to cross compile FFmpeg. Signed-off-by: lizzie lizzie@eden-emu.dev Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2973 Reviewed-by: crueter Reviewed-by: MaranBr --- externals/cmake-modules/DetectPlatform.cmake | 4 + externals/ffmpeg/CMakeLists.txt | 182 ++++++++++++------- 2 files changed, 120 insertions(+), 66 deletions(-) diff --git a/externals/cmake-modules/DetectPlatform.cmake b/externals/cmake-modules/DetectPlatform.cmake index 6475884f1f..de1a85b793 100644 --- a/externals/cmake-modules/DetectPlatform.cmake +++ b/externals/cmake-modules/DetectPlatform.cmake @@ -17,6 +17,10 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") set(PLATFORM_SUN ON) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenOrbis") + set(PLATFORM_PS4 ON) +elseif (${CMAKE_SYSTEM_NAME} STREQUAL "managarm") + set(PLATFORM_MANAGARM ON) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") set(PLATFORM_FREEBSD ON) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD") diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt index fcc48c71c4..2d85876ad2 100644 --- a/externals/ffmpeg/CMakeLists.txt +++ b/externals/ffmpeg/CMakeLists.txt @@ -11,63 +11,105 @@ set(FFmpeg_HWACCEL_FLAGS) set(FFmpeg_HWACCEL_INCLUDE_DIRS) set(FFmpeg_HWACCEL_LDFLAGS) -if (UNIX AND NOT ANDROID) - find_package(PkgConfig REQUIRED) - if (NOT ANDROID) - pkg_check_modules(LIBVA libva) - pkg_check_modules(CUDA cuda) - pkg_check_modules(FFNVCODEC ffnvcodec) - pkg_check_modules(VDPAU vdpau) +if (NOT YUZU_USE_BUNDLED_FFMPEG) + set(FFmpeg_CROSS_COMPILE_FLAGS "") + if (ANDROID) + # TODO: Maybe use CMAKE_SYSROOT? and probably provide a toolchain file for android + # I mean isn't that the "proper" way anyways? + string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" FFmpeg_HOST_SYSTEM_NAME) + set(TOOLCHAIN "${ANDROID_NDK}/toolchains/llvm/prebuilt/${FFmpeg_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}") + set(SYSROOT "${TOOLCHAIN}/sysroot") + set(FFmpeg_CPU "armv8-a") + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS + --enable-cross-compile + --arch=arm64 + #--cpu=${FFmpeg_CPU} + --cross-prefix="${TOOLCHAIN}/bin/aarch64-linux-android-" + --sysroot="${SYSROOT}" + --target-os=android + --extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld" + --extra-ldflags="-nostdlib" + ) + set(FFmpeg_IS_CROSS_COMPILING TRUE) + # User attempts to do a FFmpeg cross compilation because... + # Here we just quickly test against host/system processors not matching + # TODO: Test for versions not matching as well? + elseif (NOT (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES CMAKE_SYSTEM_PROCESSOR + AND CMAKE_HOST_SYSTEM_NAME MATCHES CMAKE_SYSTEM_NAME)) + string(TOLOWER "${CMAKE_SYSTEM_NAME}" FFmpeg_SYSTEM_NAME) + if (FFmpeg_SYSTEM_NAME STREQUAL "openorbis" OR FFmpeg_SYSTEM_NAME STREQUAL "managarm") + set(FFmpeg_SYSTEM_NAME "none") + endif() + # TODO: Can we really do better? Auto-detection? Something clever? + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS + --enable-cross-compile + --arch="${CMAKE_SYSTEM_PROCESSOR}" + --target-os="${FFmpeg_SYSTEM_NAME}" + --sysroot="${CMAKE_SYSROOT}" + ) + if (DEFINED FFmpeg_CROSS_PREFIX) + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS --cross-prefix="${FFmpeg_CROSS_PREFIX}") + else() + message(WARNING "Please set FFmpeg_CROSS_PREFIX to your cross toolchain prefix, for example: \${CMAKE_STAGING_PREFIX}/bin/${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_SYSTEM_NAME}-") + endif() + set(FFmpeg_IS_CROSS_COMPILING TRUE) endif() +endif() - if (NOT APPLE) - # In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so - if(PLATFORM_SUN) - find_library(LIBDRM_LIB libdrm PATHS /usr/lib/64 /usr/lib/amd64 /usr/lib) - if(LIBDRM_LIB) +if (PLATFORM_PS4 OR PLATFORM_MANAGARM) + # Doesn't support VA-API, don't go thru the embarrassment of trying to enable it + list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi) +elseif (UNIX AND NOT DEFINED FFmpeg_IS_CROSS_COMPILING) + find_package(PkgConfig REQUIRED) + pkg_check_modules(LIBVA libva) + pkg_check_modules(CUDA cuda) + pkg_check_modules(FFNVCODEC ffnvcodec) + pkg_check_modules(VDPAU vdpau) + + find_package(X11) + if(X11_FOUND) + if (NOT APPLE) + # In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so + if(PLATFORM_SUN) list(APPEND FFmpeg_HWACCEL_LIBRARIES X11 - "${LIBDRM_LIB}") - message(STATUS "Found libdrm at: ${LIBDRM_LIB}") + "${CMAKE_SYSROOT}/usr/lib/xorg/amd64/libdrm.so") else() - message(WARNING "libdrm not found, disabling libdrm support") - list(APPEND FFmpeg_HWACCEL_FLAGS - --disable-libdrm) + pkg_check_modules(LIBDRM libdrm REQUIRED) + list(APPEND FFmpeg_HWACCEL_LIBRARIES + ${LIBDRM_LIBRARIES}) + list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS + ${LIBDRM_INCLUDE_DIRS}) endif() - else() - pkg_check_modules(LIBDRM libdrm REQUIRED) - list(APPEND FFmpeg_HWACCEL_LIBRARIES - ${LIBDRM_LIBRARIES}) - list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS - ${LIBDRM_INCLUDE_DIRS}) list(APPEND FFmpeg_HWACCEL_FLAGS --enable-libdrm) endif() - endif() - - if(LIBVA_FOUND) - find_package(X11 REQUIRED) - pkg_check_modules(LIBVA-DRM libva-drm REQUIRED) - pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED) - list(APPEND FFmpeg_HWACCEL_LIBRARIES - ${X11_LIBRARIES} - ${LIBVA-DRM_LIBRARIES} - ${LIBVA-X11_LIBRARIES} - ${LIBVA_LIBRARIES}) - list(APPEND FFmpeg_HWACCEL_FLAGS - --enable-hwaccel=h264_vaapi - --enable-hwaccel=vp8_vaapi - --enable-hwaccel=vp9_vaapi) - list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS - ${X11_INCLUDE_DIRS} - ${LIBVA-DRM_INCLUDE_DIRS} - ${LIBVA-X11_INCLUDE_DIRS} - ${LIBVA_INCLUDE_DIRS} - ) - message(STATUS "ffmpeg: va-api libraries version ${LIBVA_VERSION} found") + if(LIBVA_FOUND) + pkg_check_modules(LIBVA-DRM libva-drm REQUIRED) + pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED) + list(APPEND FFmpeg_HWACCEL_LIBRARIES + ${X11_LIBRARIES} + ${LIBVA-DRM_LIBRARIES} + ${LIBVA-X11_LIBRARIES} + ${LIBVA_LIBRARIES}) + list(APPEND FFmpeg_HWACCEL_FLAGS + --enable-hwaccel=h264_vaapi + --enable-hwaccel=vp8_vaapi + --enable-hwaccel=vp9_vaapi) + list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS + ${X11_INCLUDE_DIRS} + ${LIBVA-DRM_INCLUDE_DIRS} + ${LIBVA-X11_INCLUDE_DIRS} + ${LIBVA_INCLUDE_DIRS} + ) + message(STATUS "ffmpeg: va-api libraries version ${LIBVA_VERSION} found") + else() + list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi) + message(WARNING "ffmpeg: libva-dev not found, disabling Video Acceleration API (VA-API)...") + endif() else() list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi) - message(WARNING "ffmpeg: libva-dev not found, disabling Video Acceleration API (VA-API)...") + message(WARNING "ffmpeg: X11 libraries not found, disabling VA-API...") endif() if (FFNVCODEC_FOUND) @@ -111,6 +153,28 @@ if (UNIX AND NOT ANDROID) endif() endif() +if (PLATFORM_PS4) + list(APPEND FFmpeg_CROSS_COMPILE_LIBS + -lkernel + -lSceUserService + -lSceSysmodule + -lSceNet + -lSceLibcInternal + ) + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS + --disable-pthreads + --extra-cflags=${CMAKE_SYSROOT}/usr/include + --extra-cxxflags=${CMAKE_SYSROOT}/usr/include + --extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}" + ) +elseif (PLATFORM_MANAGARM) + # Required for proper stuff + list(APPEND FFmpeg_CROSS_COMPILE_FLAGS + --disable-pthreads + --extra-libs="${FFmpeg_CROSS_COMPILE_LIBS}" + ) +endif() + if (YUZU_USE_BUNDLED_FFMPEG) AddJsonPackage(ffmpeg-ci) @@ -181,24 +245,6 @@ else() find_program(BASH_PROGRAM bash REQUIRED) - set(FFmpeg_CROSS_COMPILE_FLAGS "") - if (ANDROID) - string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" FFmpeg_HOST_SYSTEM_NAME) - set(TOOLCHAIN "${ANDROID_NDK}/toolchains/llvm/prebuilt/${FFmpeg_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}") - set(SYSROOT "${TOOLCHAIN}/sysroot") - set(FFmpeg_CPU "armv8-a") - list(APPEND FFmpeg_CROSS_COMPILE_FLAGS - --arch=arm64 - #--cpu=${FFmpeg_CPU} - --enable-cross-compile - --cross-prefix=${TOOLCHAIN}/bin/aarch64-linux-android- - --sysroot=${SYSROOT} - --target-os=android - --extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld" - --extra-ldflags="-nostdlib" - ) - endif() - # `configure` parameters builds only exactly what yuzu needs from FFmpeg # `--disable-vdpau` is needed to avoid linking issues set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER}) @@ -221,8 +267,12 @@ else() --enable-decoder=vp9 --enable-filter=yadif,scale --enable-pic - --cc="${FFmpeg_CC}" - --cxx="${FFmpeg_CXX}" + --cc=${FFmpeg_CC} + --cxx=${FFmpeg_CXX} + --ld=${CMAKE_LINKER} + --extra-cflags=${CMAKE_C_FLAGS} + --extra-cxxflags=${CMAKE_CXX_FLAGS} + --extra-ldflags=${CMAKE_C_LINK_FLAGS} ${FFmpeg_HWACCEL_FLAGS} ${FFmpeg_CROSS_COMPILE_FLAGS} WORKING_DIRECTORY From 707e8afb2917c7652dbe006961ba8ae735cd79d8 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 9 May 2026 05:26:17 +0200 Subject: [PATCH 17/58] [common] remove logging thread, simply write in place like a maniac (#3928) theoretically, it's better because distributes load of logging across various threads this should work because 99% of I/O solutions are blocking by default EXCEPT, maybe android differs? please check logcat didn't get affected (again) by me underestimating android ~~stupidity~~ brillaince Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3928 Reviewed-by: CamilleLaVey --- src/common/logging.cpp | 58 ++++++++++++------------------------------ 1 file changed, 16 insertions(+), 42 deletions(-) diff --git a/src/common/logging.cpp b/src/common/logging.cpp index 0b82d3e727..68e033b129 100644 --- a/src/common/logging.cpp +++ b/src/common/logging.cpp @@ -349,35 +349,8 @@ struct Impl { // Well, I mean it's the default constructor! explicit Impl() noexcept : filter(Level::Trace) {} - void StartBackendThread() noexcept { - backend_thread = std::jthread([this](std::stop_token stop_token) { - Common::SetCurrentThreadName("Logger"); - Entry entry; - const auto write_logs = [this, &entry]() { - ForEachBackend([&entry](Backend& backend) { - backend.Write(entry); - }); - }; - do { - message_queue.PopWait(entry, stop_token); - write_logs(); - } while (!stop_token.stop_requested()); - // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a - // case where a system is repeatedly spamming logs even on close. - int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100; - while (max_logs_to_write-- && message_queue.TryPop(entry)) - write_logs(); - }); - } - - void StopBackendThread() noexcept { - backend_thread.request_stop(); - if (backend_thread.joinable()) - backend_thread.join(); - ForEachBackend([](Backend& backend) { backend.Flush(); }); - } - - void ForEachBackend(auto lambda) noexcept { + template + void ForEachBackend(F&& lambda) noexcept { lambda(static_cast(color_console_backend)); #ifndef __OPENORBIS__ if (file_backend) @@ -402,9 +375,7 @@ struct Impl { #ifdef ANDROID LogcatBackend lc_backend{}; #endif - MPSCQueue message_queue{}; std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; - std::jthread backend_thread; }; } // namespace @@ -428,13 +399,11 @@ void Initialize() { } void Start() { - if (logging_instance) - logging_instance->StartBackendThread(); } void Stop() { if (logging_instance) - logging_instance->StopBackendThread(); + logging_instance->ForEachBackend([](Backend& backend) { backend.Flush(); }); } void SetGlobalFilter(const Filter& filter) { @@ -449,14 +418,19 @@ void SetColorConsoleBackendEnabled(bool enabled) { void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, unsigned int line_num, const char* function, fmt::string_view format, const fmt::format_args& args) { if (logging_instance && logging_instance->filter.CheckMessage(log_class, log_level)) { - logging_instance->message_queue.EmplaceWait(Entry{ - .message = fmt::vformat(format, args), - .timestamp = std::chrono::duration_cast(std::chrono::steady_clock::now() - logging_instance->time_origin), - .log_class = log_class, - .log_level = log_level, - .filename = TrimSourcePath(filename), - .function = function, - .line_num = line_num, + auto const flush = ::Settings::values.log_flush_line.GetValue(); + logging_instance->ForEachBackend([=](Backend& backend) { + backend.Write(Entry{ + .message = fmt::vformat(format, args), + .timestamp = std::chrono::duration_cast(std::chrono::steady_clock::now() - logging_instance->time_origin), + .log_class = log_class, + .log_level = log_level, + .filename = TrimSourcePath(filename), + .function = function, + .line_num = line_num, + }); + if (flush) + backend.Flush(); }); } } From f87b1dafc83d50b7e363409444a9a2a8fdff76cb Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 9 May 2026 05:27:33 +0200 Subject: [PATCH 18/58] [file_sys/sytem_archive] add missing identifiers for +8.0 (#3867) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3867 Reviewed-by: crueter Reviewed-by: MaranBr --- .../system_archive/system_archive.cpp | 138 ++++++++---------- 1 file changed, 64 insertions(+), 74 deletions(-) diff --git a/src/core/file_sys/system_archive/system_archive.cpp b/src/core/file_sys/system_archive/system_archive.cpp index cb68d5b55e..bbdf27039b 100644 --- a/src/core/file_sys/system_archive/system_archive.cpp +++ b/src/core/file_sys/system_archive/system_archive.cpp @@ -15,86 +15,76 @@ namespace FileSys::SystemArchive { -constexpr u64 SYSTEM_ARCHIVE_BASE_TITLE_ID = 0x0100000000000800; -constexpr std::size_t SYSTEM_ARCHIVE_COUNT = 0x28; - -using SystemArchiveSupplier = VirtualDir (*)(); - struct SystemArchiveDescriptor { - u64 title_id; const char* name; - SystemArchiveSupplier supplier; + VirtualDir (*supplier)(); }; -constexpr std::array SYSTEM_ARCHIVES{{ - {0x0100000000000800, "CertStore", nullptr}, - {0x0100000000000801, "ErrorMessage", nullptr}, - {0x0100000000000802, "MiiModel", &MiiModel}, - {0x0100000000000803, "BrowserDll", nullptr}, - {0x0100000000000804, "Help", nullptr}, - {0x0100000000000805, "SharedFont", nullptr}, - {0x0100000000000806, "NgWord", &NgWord1}, - {0x0100000000000807, "SsidList", nullptr}, - {0x0100000000000808, "Dictionary", nullptr}, - {0x0100000000000809, "SystemVersion", &SystemVersion}, - {0x010000000000080A, "AvatarImage", nullptr}, - {0x010000000000080B, "LocalNews", nullptr}, - {0x010000000000080C, "Eula", nullptr}, - {0x010000000000080D, "UrlBlackList", nullptr}, - {0x010000000000080E, "TimeZoneBinary", &TimeZoneBinary}, - {0x010000000000080F, "CertStoreCruiser", nullptr}, - {0x0100000000000810, "FontNintendoExtension", &FontNintendoExtension}, - {0x0100000000000811, "FontStandard", &FontStandard}, - {0x0100000000000812, "FontKorean", &FontKorean}, - {0x0100000000000813, "FontChineseTraditional", &FontChineseTraditional}, - {0x0100000000000814, "FontChineseSimple", &FontChineseSimple}, - {0x0100000000000815, "FontBfcpx", nullptr}, - {0x0100000000000816, "SystemUpdate", nullptr}, - {0x0100000000000817, "0100000000000817", nullptr}, - {0x0100000000000818, "FirmwareDebugSettings", nullptr}, - {0x0100000000000819, "BootImagePackage", nullptr}, - {0x010000000000081A, "BootImagePackageSafe", nullptr}, - {0x010000000000081B, "BootImagePackageExFat", nullptr}, - {0x010000000000081C, "BootImagePackageExFatSafe", nullptr}, - {0x010000000000081D, "FatalMessage", nullptr}, - {0x010000000000081E, "ControllerIcon", nullptr}, - {0x010000000000081F, "PlatformConfigIcosa", nullptr}, - {0x0100000000000820, "PlatformConfigCopper", nullptr}, - {0x0100000000000821, "PlatformConfigHoag", nullptr}, - {0x0100000000000822, "ControllerFirmware", nullptr}, - {0x0100000000000823, "NgWord2", &NgWord2}, - {0x0100000000000824, "PlatformConfigIcosaMariko", nullptr}, - {0x0100000000000825, "ApplicationBlackList", nullptr}, - {0x0100000000000826, "RebootlessSystemUpdateVersion", nullptr}, - {0x0100000000000827, "ContentActionTable", nullptr}, -}}; +constexpr inline SystemArchiveDescriptor GetSystemArchive(u64 title_id) { + switch (title_id) { + case 0x0100000000000800: return {"CertStore", nullptr}; + case 0x0100000000000801: return {"ErrorMessage", nullptr}; + case 0x0100000000000802: return {"MiiModel", &MiiModel}; + case 0x0100000000000803: return {"BrowserDll", nullptr}; + case 0x0100000000000804: return {"Help", nullptr}; + case 0x0100000000000805: return {"SharedFont", nullptr}; + case 0x0100000000000806: return {"NgWord", &NgWord1}; + case 0x0100000000000807: return {"SsidList", nullptr}; + case 0x0100000000000808: return {"Dictionary", nullptr}; + case 0x0100000000000809: return {"SystemVersion", &SystemVersion}; + case 0x010000000000080A: return {"AvatarImage", nullptr}; + case 0x010000000000080B: return {"LocalNews", nullptr}; + case 0x010000000000080C: return {"Eula", nullptr}; + case 0x010000000000080D: return {"UrlBlackList", nullptr}; + case 0x010000000000080E: return {"TimeZoneBinary", &TimeZoneBinary}; + case 0x010000000000080F: return {"CertStoreCruiser", nullptr}; + case 0x0100000000000810: return {"FontNintendoExtension", &FontNintendoExtension}; + case 0x0100000000000811: return {"FontStandard", &FontStandard}; + case 0x0100000000000812: return {"FontKorean", &FontKorean}; + case 0x0100000000000813: return {"FontChineseTraditional", &FontChineseTraditional}; + case 0x0100000000000814: return {"FontChineseSimple", &FontChineseSimple}; + case 0x0100000000000815: return {"FontBfcpx", nullptr}; + case 0x0100000000000816: return {"SystemUpdate", nullptr}; + case 0x0100000000000817: return {"0100000000000817", nullptr}; + case 0x0100000000000818: return {"FirmwareDebugSettings", nullptr}; + case 0x0100000000000819: return {"BootImagePackage", nullptr}; + case 0x010000000000081A: return {"BootImagePackageSafe", nullptr}; + case 0x010000000000081B: return {"BootImagePackageExFat", nullptr}; + case 0x010000000000081C: return {"BootImagePackageExFatSafe", nullptr}; + case 0x010000000000081D: return {"FatalMessage", nullptr}; + case 0x010000000000081E: return {"ControllerIcon", nullptr}; + case 0x010000000000081F: return {"PlatformConfigIcosa", nullptr}; + case 0x0100000000000820: return {"PlatformConfigCopper", nullptr}; + case 0x0100000000000821: return {"PlatformConfigHoag", nullptr}; + case 0x0100000000000822: return {"ControllerFirmware", nullptr}; + case 0x0100000000000823: return {"NgWord2", &NgWord2}; + case 0x0100000000000824: return {"PlatformConfigIcosaMariko", nullptr}; + case 0x0100000000000825: return {"ApplicationBlackList", nullptr}; + case 0x0100000000000826: return {"RebootlessSystemUpdateVersion", nullptr}; + case 0x0100000000000827: return {"ContentActionTable", nullptr}; + case 0x0100000000000828: return {"FunctionBlackList", nullptr}; + case 0x0100000000000829: return {"PlatformConfigCalcio", nullptr}; + case 0x0100000000000830: return {"NgWordT", nullptr}; + case 0x0100000000000831: return {"PlatformConfigAula", nullptr}; + case 0x0100000000000832: return {"CradleFirmware", nullptr}; + case 0x0100000000000835: return {"ErrorMessageUtf8", nullptr}; + case 0x0100000000000859: return {"ClientCertData", nullptr}; + case 0x010000000000085C: return {"GameCardConfigurationData", nullptr}; + default: return {nullptr, nullptr}; + } +} VirtualFile SynthesizeSystemArchive(const u64 title_id) { - if (title_id < SYSTEM_ARCHIVES.front().title_id || title_id > SYSTEM_ARCHIVES.back().title_id) { - return nullptr; + auto const desc = GetSystemArchive(title_id); + LOG_INFO(Service_FS, "Synthesizing system archive '{}' (0x{:016X}).", desc.name, title_id); + if (desc.supplier != nullptr) { + if (auto const dir = desc.supplier(); dir != nullptr) { + if (auto const romfs = CreateRomFS(dir); romfs != nullptr) { + LOG_INFO(Service_FS, " - System archive generation successful!"); + return romfs; + } + } } - - const auto& desc = SYSTEM_ARCHIVES[title_id - SYSTEM_ARCHIVE_BASE_TITLE_ID]; - - LOG_INFO(Service_FS, "Synthesizing system archive '{}' (0x{:016X}).", desc.name, desc.title_id); - - if (desc.supplier == nullptr) { - return nullptr; - } - - const auto dir = desc.supplier(); - - if (dir == nullptr) { - return nullptr; - } - - const auto romfs = CreateRomFS(dir); - - if (romfs == nullptr) { - return nullptr; - } - - LOG_INFO(Service_FS, " - System archive generation successful!"); - return romfs; + return nullptr; } } // namespace FileSys::SystemArchive From a6423a88cc068f8213db8707900a1d1b38b9566d Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 9 May 2026 05:28:22 +0200 Subject: [PATCH 19/58] [file_sys] resize SD card size in 4GiB chunks (#3921) some homebrew theoretically would freak out when 1TB is reached... so let's just magically resize the SD card :) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3921 Reviewed-by: CamilleLaVey --- src/core/file_sys/sdmc_factory.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index f3e2e21f4c..a2903dbacf 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp @@ -1,7 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include +#include "common/alignment.h" +#include "common/literals.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/sdmc_factory.h" #include "core/file_sys/vfs/vfs.h" @@ -9,8 +14,6 @@ namespace FileSys { -constexpr u64 SDMC_TOTAL_SIZE = 0x10000000000; // 1 TiB - SDMCFactory::SDMCFactory(VirtualDir sd_dir_, VirtualDir sd_mod_dir_) : sd_dir(std::move(sd_dir_)), sd_mod_dir(std::move(sd_mod_dir_)), contents(std::make_unique( @@ -56,7 +59,11 @@ u64 SDMCFactory::GetSDMCFreeSpace() const { } u64 SDMCFactory::GetSDMCTotalSpace() const { - return SDMC_TOTAL_SIZE; + // Resize the SD space automatically, always leaving around 4GiB last from next chunk block + using namespace Common::Literals; + auto const bytes_per_sector = 512; + auto const size_block = (sd_dir->GetSize() + 4_GiB) / 4_GiB; + return Common::AlignUp(size_block * 4_GiB, bytes_per_sector); } } // namespace FileSys From eec460ec2ef13dee7376f2854ba00da9a98b0cd5 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 9 May 2026 05:41:41 +0200 Subject: [PATCH 20/58] [dynarmic] remove decode matcher function handlers using std::function<>, use raw function pointers (#3920) issues: - std::function<> is used, which is famously bad - storage of tehse in tables makes big fucking tables for no good reason - lets just store a normal pointer and stuff! :) this pr attempts to address that Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3920 Reviewed-by: CamilleLaVey --- src/core/arm/nce/interpreter_visitor.cpp | 7 +- .../src/dynarmic/frontend/A32/decoder/arm.h | 65 ++++++------- .../src/dynarmic/frontend/A32/decoder/asimd.h | 17 ++-- .../dynarmic/frontend/A32/decoder/thumb16.h | 17 ++-- .../dynarmic/frontend/A32/decoder/thumb32.h | 17 ++-- .../src/dynarmic/frontend/A32/decoder/vfp.h | 34 ++----- .../frontend/A32/translate/translate_arm.cpp | 24 ++--- .../A32/translate/translate_thumb.cpp | 40 ++++---- .../src/dynarmic/frontend/A64/decoder/a64.h | 64 ++++++------- .../frontend/A64/translate/a64_translate.cpp | 15 +-- .../frontend/decoder/decoder_detail.h | 93 ++++++------------- .../src/dynarmic/frontend/decoder/matcher.h | 51 +++++----- src/dynarmic/src/dynarmic/frontend/imm.h | 5 +- src/dynarmic/tests/decoder_tests.cpp | 2 +- src/dynarmic/tests/print_info.cpp | 12 +-- 15 files changed, 187 insertions(+), 276 deletions(-) diff --git a/src/core/arm/nce/interpreter_visitor.cpp b/src/core/arm/nce/interpreter_visitor.cpp index 077a696cc8..ec2b155fe4 100644 --- a/src/core/arm/nce/interpreter_visitor.cpp +++ b/src/core/arm/nce/interpreter_visitor.cpp @@ -761,8 +761,7 @@ bool InterpreterVisitor::LDR_reg_fpsimd(Imm<2> size, Imm<1> opc_1, Reg Rm, Imm<3 return this->SIMDOffset(scale, shift, opc_0, Rm, option, Rn, Vt); } -std::optional MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context, - fpsimd_context* fpsimd_context) { +std::optional MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context, fpsimd_context* fpsimd_context) { std::span regs(reinterpret_cast(context->regs), 31); std::span vregs(reinterpret_cast(fpsimd_context->vregs), 32); u64& sp = *reinterpret_cast(&context->sp); @@ -772,9 +771,9 @@ std::optional MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, m u32 instruction = memory.Read32(pc); bool was_executed = false; - auto decoder = Dynarmic::A64::Decode(instruction); + auto decoder = Dynarmic::A64::Decode(visitor, instruction); if (decoder) { - was_executed = decoder->get().call(visitor, instruction); + was_executed = *decoder; } else { was_executed = false; } diff --git a/src/dynarmic/src/dynarmic/frontend/A32/decoder/arm.h b/src/dynarmic/src/dynarmic/frontend/A32/decoder/arm.h index d1cd9a923d..a9309ef5a8 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/decoder/arm.h +++ b/src/dynarmic/src/dynarmic/frontend/A32/decoder/arm.h @@ -26,48 +26,41 @@ namespace Dynarmic::A32 { template using ArmMatcher = Decoder::Matcher; -template -using ArmDecodeTable = std::array>, 0x1000>; - -namespace detail { -inline size_t ToFastLookupIndexArm(u32 instruction) noexcept { - return ((instruction >> 4) & 0x00F) | ((instruction >> 16) & 0xFF0); -} -} // namespace detail - -template -static ArmDecodeTable GetArmDecodeTable() noexcept { - ArmDecodeTable table{}; - for (size_t i = 0; i < table.size(); ++i) { - // PLEASE HEAP ELLIDE - for (auto const& e : std::vector>{ -#define INST(fn, name, bitstring) DYNARMIC_DECODER_GET_MATCHER(ArmMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)), +template +static std::optional DecodeArm(V& visitor, u32 instruction) noexcept { + auto const make_fast_index = [](u32 a) { + return ((a >> 4) & 0x00F) | ((a >> 16) & 0xFF0); + }; + struct Handler { + bool (*fn)(V&, u32); + u32 mask; + u32 expect; + }; + alignas(64) static const std::array, 0x1000> table = [&] { + std::array, 0x1000> t{}; + for (size_t i = 0; i < t.size(); ++i) { +#define INST(fn, name, bitstring) \ + do { \ + auto const [mask, expect] = DYNARMIC_DECODER_GET_MATCHER(ArmMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + if ((i & make_fast_index(mask)) == make_fast_index(expect)) { \ + t[i].emplace_back([](V& visitor, u32 instruction) -> bool { \ + return DYNARMIC_DECODER_GET_MATCHER_FUNCTION(ArmMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + }, mask, expect); \ + } \ + } while (0); #include "./arm.inc" #undef INST - }) { - auto const expect = detail::ToFastLookupIndexArm(e.GetExpected()); - auto const mask = detail::ToFastLookupIndexArm(e.GetMask()); - if ((i & mask) == expect) { - table[i].push_back(e); - } } - } - return table; + return t; + }(); + for (auto const& e : table[make_fast_index(instruction)]) + if ((instruction & e.mask) == e.expect) + return e.fn(visitor, instruction); + return std::nullopt; } template -static std::optional>> DecodeArm(u32 instruction) noexcept { - alignas(64) static const auto table = GetArmDecodeTable(); - const auto matches_instruction = [instruction](const auto& matcher) { - return matcher.Matches(instruction); - }; - const auto& subtable = table[detail::ToFastLookupIndexArm(instruction)]; - auto iter = std::find_if(subtable.begin(), subtable.end(), matches_instruction); - return iter != subtable.end() ? std::optional>>(*iter) : std::nullopt; -} - -template -static std::optional GetNameARM(u32 inst) noexcept { +static std::optional GetNameArm(u32 inst) noexcept { std::vector>> list = { #define INST(fn, name, bitstring) { name, DYNARMIC_DECODER_GET_MATCHER(ArmMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)) }, #include "./arm.inc" diff --git a/src/dynarmic/src/dynarmic/frontend/A32/decoder/asimd.h b/src/dynarmic/src/dynarmic/frontend/A32/decoder/asimd.h index 5b0336e59f..4feae6f478 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/decoder/asimd.h +++ b/src/dynarmic/src/dynarmic/frontend/A32/decoder/asimd.h @@ -26,17 +26,16 @@ namespace Dynarmic::A32 { template using ASIMDMatcher = Decoder::Matcher; -template -static std::optional>> DecodeASIMD(u32 instruction) noexcept { - alignas(64) static const auto table = std::array{ -#define INST(fn, name, bitstring) DYNARMIC_DECODER_GET_MATCHER(ASIMDMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)), +template +static std::optional DecodeASIMD(V& visitor, u32 instruction) noexcept { +#define INST(fn, name, bitstring) \ + do { \ + auto const [mask, expect] = DYNARMIC_DECODER_GET_MATCHER(ASIMDMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + if ((instruction & mask) == expect) return DYNARMIC_DECODER_GET_MATCHER_FUNCTION(ASIMDMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + } while (0); #include "./asimd.inc" #undef INST - }; - auto iter = std::find_if(table.begin(), table.end(), [instruction](const auto& matcher) { - return matcher.Matches(instruction); - }); - return iter != table.end() ? std::optional>>(*iter) : std::nullopt; + return std::nullopt; } template diff --git a/src/dynarmic/src/dynarmic/frontend/A32/decoder/thumb16.h b/src/dynarmic/src/dynarmic/frontend/A32/decoder/thumb16.h index 590878a6de..465159a00d 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/decoder/thumb16.h +++ b/src/dynarmic/src/dynarmic/frontend/A32/decoder/thumb16.h @@ -23,17 +23,16 @@ namespace Dynarmic::A32 { template using Thumb16Matcher = Decoder::Matcher; -template -static std::optional>> DecodeThumb16(u16 instruction) { - alignas(64) static const auto table = std::array{ -#define INST(fn, name, bitstring) DYNARMIC_DECODER_GET_MATCHER(Thumb16Matcher, fn, name, Decoder::detail::StringToArray<16>(bitstring)), +template +static std::optional DecodeThumb16(V& visitor, u16 instruction) { +#define INST(fn, name, bitstring) \ + do { \ + auto const [mask, expect] = DYNARMIC_DECODER_GET_MATCHER(Thumb16Matcher, fn, name, Decoder::detail::StringToArray<16>(bitstring)); \ + if ((instruction & mask) == expect) return DYNARMIC_DECODER_GET_MATCHER_FUNCTION(Thumb16Matcher, fn, name, Decoder::detail::StringToArray<16>(bitstring)); \ + } while (0); #include "./thumb16.inc" #undef INST - }; - auto iter = std::find_if(table.begin(), table.end(), [instruction](const auto& matcher) { - return matcher.Matches(instruction); - }); - return iter != table.end() ? std::optional>>(*iter) : std::nullopt; + return std::nullopt; } template diff --git a/src/dynarmic/src/dynarmic/frontend/A32/decoder/thumb32.h b/src/dynarmic/src/dynarmic/frontend/A32/decoder/thumb32.h index 6a09c66afb..b3588c7a1d 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/decoder/thumb32.h +++ b/src/dynarmic/src/dynarmic/frontend/A32/decoder/thumb32.h @@ -22,17 +22,16 @@ namespace Dynarmic::A32 { template using Thumb32Matcher = Decoder::Matcher; -template -static std::optional>> DecodeThumb32(u32 instruction) { - alignas(64) static const auto table = std::array{ -#define INST(fn, name, bitstring) DYNARMIC_DECODER_GET_MATCHER(Thumb32Matcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)), +template +static std::optional DecodeThumb32(V& visitor, u32 instruction) { +#define INST(fn, name, bitstring) \ + do { \ + auto const [mask, expect] = DYNARMIC_DECODER_GET_MATCHER(Thumb32Matcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + if ((instruction & mask) == expect) return DYNARMIC_DECODER_GET_MATCHER_FUNCTION(Thumb32Matcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + } while (0); #include "./thumb32.inc" #undef INST - }; - auto iter = std::find_if(table.begin(), table.end(), [instruction](const auto& matcher) { - return matcher.Matches(instruction); - }); - return iter != table.end() ? std::optional>>(*iter) : std::nullopt; + return std::nullopt; } template diff --git a/src/dynarmic/src/dynarmic/frontend/A32/decoder/vfp.h b/src/dynarmic/src/dynarmic/frontend/A32/decoder/vfp.h index e02cc03a6b..8703aa24b4 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/decoder/vfp.h +++ b/src/dynarmic/src/dynarmic/frontend/A32/decoder/vfp.h @@ -23,32 +23,18 @@ namespace Dynarmic::A32 { template using VFPMatcher = Decoder::Matcher; -template -static std::optional>> DecodeVFP(u32 instruction) { - using Table = std::vector>; - alignas(64) static const struct Tables { - Table unconditional; - Table conditional; - } tables = []() { - Table list = { -#define INST(fn, name, bitstring) DYNARMIC_DECODER_GET_MATCHER(VFPMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)), +template +static std::optional DecodeVFP(V& visitor, u32 instruction) { + bool const i_uncond = (instruction & 0xF0000000) == 0xF0000000; +#define INST(fn, name, bitstring) \ + do { \ + auto const [mask, expect] = DYNARMIC_DECODER_GET_MATCHER(VFPMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + bool const m_uncond = (mask & 0xF0000000) == 0xF0000000; \ + if ((instruction & mask) == expect && m_uncond == i_uncond) return DYNARMIC_DECODER_GET_MATCHER_FUNCTION(VFPMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + } while (0); #include "./vfp.inc" #undef INST - }; - auto const it = std::stable_partition(list.begin(), list.end(), [&](const auto& matcher) { - return (matcher.GetMask() & 0xF0000000) == 0xF0000000; - }); - return Tables{ - Table{list.begin(), it}, - Table{it, list.end()}, - }; - }(); - const bool is_unconditional = (instruction & 0xF0000000) == 0xF0000000; - const Table& table = is_unconditional ? tables.unconditional : tables.conditional; - auto iter = std::find_if(table.begin(), table.end(), [instruction](const auto& matcher) { - return matcher.Matches(instruction); - }); - return iter != table.end() ? std::optional>>(*iter) : std::nullopt; + return std::nullopt; } template diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp index 3fd475d074..6c89a4af36 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp @@ -41,12 +41,12 @@ void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCall tcb->PreCodeTranslationHook(false, arm_pc, visitor.ir); ticks_for_instruction = tcb->GetTicksForCode(false, arm_pc, *arm_instruction); - if (const auto vfp_decoder = DecodeVFP(*arm_instruction)) { - should_continue = vfp_decoder->get().call(visitor, *arm_instruction); - } else if (const auto asimd_decoder = DecodeASIMD(*arm_instruction)) { - should_continue = asimd_decoder->get().call(visitor, *arm_instruction); - } else if (const auto decoder = DecodeArm(*arm_instruction)) { - should_continue = decoder->get().call(visitor, *arm_instruction); + if (const auto vfp_decoder = DecodeVFP(visitor, *arm_instruction)) { + should_continue = *vfp_decoder; + } else if (const auto asimd_decoder = DecodeASIMD(visitor, *arm_instruction)) { + should_continue = *asimd_decoder; + } else if (const auto decoder = DecodeArm(visitor, *arm_instruction)) { + should_continue = *decoder; } else { should_continue = visitor.arm_UDF(); } @@ -88,12 +88,12 @@ bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descript const u64 ticks_for_instruction = 1; - if (const auto vfp_decoder = DecodeVFP(arm_instruction)) { - should_continue = vfp_decoder->get().call(visitor, arm_instruction); - } else if (const auto asimd_decoder = DecodeASIMD(arm_instruction)) { - should_continue = asimd_decoder->get().call(visitor, arm_instruction); - } else if (const auto decoder = DecodeArm(arm_instruction)) { - should_continue = decoder->get().call(visitor, arm_instruction); + if (const auto vfp_decoder = DecodeVFP(visitor, arm_instruction)) { + should_continue = *vfp_decoder; + } else if (const auto asimd_decoder = DecodeASIMD(visitor, arm_instruction)) { + should_continue = *asimd_decoder; + } else if (const auto decoder = DecodeArm(visitor, arm_instruction)) { + should_continue = *decoder; } else { should_continue = visitor.arm_UDF(); } diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp index 332860a95c..2a2fbea63f 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp @@ -126,24 +126,24 @@ void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCa if (IsUnconditionalInstruction(is_thumb_16, thumb_instruction) || visitor.ThumbConditionPassed()) { if (is_thumb_16) { - if (const auto decoder = DecodeThumb16(static_cast(thumb_instruction))) { - should_continue = decoder->get().call(visitor, static_cast(thumb_instruction)); + if (const auto decoder = DecodeThumb16(visitor, u16(thumb_instruction))) { + should_continue = *decoder; } else { should_continue = visitor.thumb16_UDF(); } } else { if (MaybeVFPOrASIMDInstruction(thumb_instruction)) { - if (const auto vfp_decoder = DecodeVFP(thumb_instruction)) { - should_continue = vfp_decoder->get().call(visitor, thumb_instruction); - } else if (const auto asimd_decoder = DecodeASIMD(ConvertASIMDInstruction(thumb_instruction))) { - should_continue = asimd_decoder->get().call(visitor, ConvertASIMDInstruction(thumb_instruction)); - } else if (const auto decoder = DecodeThumb32(thumb_instruction)) { - should_continue = decoder->get().call(visitor, thumb_instruction); + if (const auto vfp_decoder = DecodeVFP(visitor, thumb_instruction)) { + should_continue = *vfp_decoder; + } else if (const auto asimd_decoder = DecodeASIMD(visitor, ConvertASIMDInstruction(thumb_instruction))) { + should_continue = *asimd_decoder; + } else if (const auto decoder = DecodeThumb32(visitor, thumb_instruction)) { + should_continue = *decoder; } else { should_continue = visitor.thumb32_UDF(); } - } else if (const auto decoder = DecodeThumb32(thumb_instruction)) { - should_continue = decoder->get().call(visitor, thumb_instruction); + } else if (const auto decoder = DecodeThumb32(visitor, thumb_instruction)) { + should_continue = *decoder; } else { should_continue = visitor.thumb32_UDF(); } @@ -187,25 +187,25 @@ bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descri const u64 ticks_for_instruction = 1; if (is_thumb_16) { - if (const auto decoder = DecodeThumb16(static_cast(thumb_instruction))) { - should_continue = decoder->get().call(visitor, static_cast(thumb_instruction)); + if (const auto decoder = DecodeThumb16(visitor, u16(thumb_instruction))) { + should_continue = *decoder; } else { should_continue = visitor.thumb16_UDF(); } } else { thumb_instruction = mcl::bit::swap_halves_32(thumb_instruction); if (MaybeVFPOrASIMDInstruction(thumb_instruction)) { - if (const auto vfp_decoder = DecodeVFP(thumb_instruction)) { - should_continue = vfp_decoder->get().call(visitor, thumb_instruction); - } else if (const auto asimd_decoder = DecodeASIMD(ConvertASIMDInstruction(thumb_instruction))) { - should_continue = asimd_decoder->get().call(visitor, ConvertASIMDInstruction(thumb_instruction)); - } else if (const auto decoder = DecodeThumb32(thumb_instruction)) { - should_continue = decoder->get().call(visitor, thumb_instruction); + if (const auto vfp_decoder = DecodeVFP(visitor, thumb_instruction)) { + should_continue = *vfp_decoder; + } else if (const auto asimd_decoder = DecodeASIMD(visitor, ConvertASIMDInstruction(thumb_instruction))) { + should_continue = *asimd_decoder; + } else if (const auto decoder = DecodeThumb32(visitor, thumb_instruction)) { + should_continue = *decoder; } else { should_continue = visitor.thumb32_UDF(); } - } else if (const auto decoder = DecodeThumb32(thumb_instruction)) { - should_continue = decoder->get().call(visitor, thumb_instruction); + } else if (const auto decoder = DecodeThumb32(visitor, thumb_instruction)) { + should_continue = *decoder; } else { should_continue = visitor.thumb32_UDF(); } diff --git a/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h b/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h index ccf890cbcd..f0b7baba7b 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h +++ b/src/dynarmic/src/dynarmic/frontend/A64/decoder/a64.h @@ -26,45 +26,37 @@ namespace Dynarmic::A64 { template using Matcher = Decoder::Matcher; -template -using DecodeTable = std::array>, 0x1000>; - -namespace detail { -inline size_t ToFastLookupIndex(u32 instruction) { - return ((instruction >> 10) & 0x00F) | ((instruction >> 18) & 0xFF0); -} -} // namespace detail - -template -inline DecodeTable GetDecodeTable() { - DecodeTable table{}; - for (size_t i = 0; i < table.size(); ++i) { - // PLEASE HEAP ELLIDE - for (auto const& e : std::vector>{ -#define INST(fn, name, bitstring) DYNARMIC_DECODER_GET_MATCHER(Matcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)), +template +static std::optional Decode(V& visitor, u32 instruction) noexcept { + auto const make_fast_index = [](u32 a) { + return ((a >> 10) & 0x00F) | ((a >> 18) & 0xFF0); + }; + struct Handler { + bool (*fn)(V&, u32); + u32 mask; + u32 expect; + }; + alignas(64) static const std::array, 0x1000> table = [&] { + std::array, 0x1000> t{}; + for (size_t i = 0; i < t.size(); ++i) { +#define INST(fn, name, bitstring) \ + do { \ + auto const [mask, expect] = DYNARMIC_DECODER_GET_MATCHER(Matcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + if ((i & make_fast_index(mask)) == make_fast_index(expect)) { \ + t[i].emplace_back([](V& visitor, u32 instruction) -> bool { \ + return DYNARMIC_DECODER_GET_MATCHER_FUNCTION(Matcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)); \ + }, mask, expect); \ + } \ + } while (0); #include "./a64.inc" #undef INST - }) { - const auto expect = detail::ToFastLookupIndex(e.GetExpected()); - const auto mask = detail::ToFastLookupIndex(e.GetMask()); - if ((i & mask) == expect) - table[i].push_back(e); } - } - return table; -} - -/// In practice it must always suceed, otherwise something else unrelated would have gone awry -template -inline std::optional>> Decode(u32 instruction) { - alignas(64) static const auto table = GetDecodeTable(); - const auto& subtable = table[detail::ToFastLookupIndex(instruction)]; - auto iter = std::find_if(subtable.begin(), subtable.end(), [instruction](const auto& matcher) { - return matcher.Matches(instruction); - }); - return iter != subtable.end() - ? std::optional{ std::reference_wrapper>(*iter) } - : std::nullopt; + return t; + }(); + for (auto const& e : table[make_fast_index(instruction)]) + if ((instruction & e.mask) == e.expect) + return e.fn(visitor, instruction); + return std::nullopt; } template diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp index 4afce6bd29..7840c63d79 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp @@ -24,9 +24,8 @@ void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFu do { const u64 pc = visitor.ir.current_location->PC(); if (const auto instruction = memory_read_code(pc)) { - auto decoder = Decode(*instruction); - if (decoder) { - should_continue = decoder->get().call(visitor, *instruction); + if (auto decoder = Decode(visitor, *instruction)) { + should_continue = *decoder; } else { should_continue = visitor.RaiseException(Exception::UnallocatedEncoding); } @@ -47,13 +46,9 @@ void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFu bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction) { TranslatorVisitor visitor{block, descriptor, {}}; - bool should_continue = true; - auto const decoder = Decode(instruction); - if (decoder) { - should_continue = decoder->get().call(visitor, instruction); - } else { - should_continue = false; - } + bool should_continue = false; + if (auto const decoder = Decode(visitor, instruction)) + should_continue = *decoder; visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4); block.CycleCount()++; diff --git a/src/dynarmic/src/dynarmic/frontend/decoder/decoder_detail.h b/src/dynarmic/src/dynarmic/frontend/decoder/decoder_detail.h index c22e585c26..e383fb0262 100644 --- a/src/dynarmic/src/dynarmic/frontend/decoder/decoder_detail.h +++ b/src/dynarmic/src/dynarmic/frontend/decoder/decoder_detail.h @@ -8,31 +8,25 @@ #pragma once -#include #include #include - +#include #include "common/assert.h" #include "dynarmic/mcl/bit.hpp" -#include "dynarmic/mcl/function_info.hpp" namespace Dynarmic::Decoder { namespace detail { template -inline consteval std::array StringToArray(const char (&str)[N + 1]) { - std::array result{}; - for (size_t i = 0; i < N; i++) { - result[i] = str[i]; - } - return result; +inline consteval std::array StringToArray(const char (&s)[N + 1]) { + std::array r{}; + for (size_t i = 0; i < N; i++) + r[i] = s[i]; + return r; } -/** - * Helper functions for the decoders. - * - * @tparam MatcherT The type of the Matcher to use. - */ +/// @brief Helper functions for the decoders. +/// @tparam MatcherT The type of the Matcher to use. template struct detail { using opcode_type = typename MatcherT::opcode_type; @@ -40,17 +34,15 @@ struct detail { static constexpr size_t opcode_bitsize = mcl::bitsizeof; - /** - * Generates the mask and the expected value after masking from a given bitstring. - * A '0' in a bitstring indicates that a zero must be present at that bit position. - * A '1' in a bitstring indicates that a one must be present at that bit position. - */ + /// @brief Generates the mask and the expected value after masking from a given bitstring. + /// A '0' in a bitstring indicates that a zero must be present at that bit position. + /// A '1' in a bitstring indicates that a one must be present at that bit position. #ifdef __clang__ static constexpr auto GetMaskAndExpect(std::array bitstring) { #else static consteval auto GetMaskAndExpect(std::array bitstring) { #endif - const auto one = static_cast(1); + const auto one = opcode_type(1); opcode_type mask = 0, expect = 0; for (size_t i = 0; i < opcode_bitsize; i++) { const size_t bit_position = opcode_bitsize - i - 1; @@ -101,7 +93,7 @@ struct detail { } #if !defined(DYNARMIC_IGNORE_ASSERTS) && !defined(__ANDROID__) // Avoids a MSVC ICE, and avoids Android NDK issue. - ASSERT(std::all_of(masks.begin(), masks.end(), [](auto m) { return m != 0; })); + DEBUG_ASSERT(std::all_of(masks.begin(), masks.end(), [](auto m) { return m != 0; })); #endif return std::make_tuple(masks, shifts); } @@ -109,65 +101,32 @@ struct detail { /// @brief This struct's Make member function generates a lambda which decodes an instruction /// based on the provided arg_masks and arg_shifts. The Visitor member function to call is /// provided as a template argument. - template - struct VisitorCaller; - #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable : 4800) // forcing value to bool 'true' or 'false' (performance warning) #endif - template - struct VisitorCaller { - template - static constexpr auto Make(std::integer_sequence, - ReturnType (V::*const fn)(Args...), - const std::array arg_masks, - const std::array arg_shifts) { - static_assert(std::is_same_v, "Member function is not from Matcher's Visitor"); - return [fn, arg_masks, arg_shifts](V& v, opcode_type instruction) { - (void)instruction; - (void)arg_masks; - (void)arg_shifts; - return (v.*fn)(Args((instruction & arg_masks[iota]) >> arg_shifts[iota])...); - }; - } - }; - - template - struct VisitorCaller { - template - static constexpr auto Make(std::integer_sequence, - ReturnType (V::*const fn)(Args...) const, - const std::array arg_masks, - const std::array arg_shifts) { - static_assert(std::is_same_v, "Member function is not from Matcher's Visitor"); - return [fn, arg_masks, arg_shifts](const V& v, opcode_type instruction) { - (void)instruction; - (void)arg_masks; - (void)arg_shifts; - return (v.*fn)(Args((instruction & arg_masks[iota]) >> arg_shifts[iota])...); - }; + template + struct VisitorCaller { + template + static inline constexpr auto Invoke(std::index_sequence, V& visitor, [[maybe_unused]] opcode_type instruction, ReturnType (V::*const fn)(Args...), [[maybe_unused]] const std::array arg_masks, [[maybe_unused]] const std::array arg_shifts) { + return (visitor.*fn)(Args((instruction & arg_masks[iota]) >> arg_shifts[iota])...); } }; #ifdef _MSC_VER # pragma warning(pop) #endif - /// @brief Creates a matcher that can match and parse instructions based on bitstring. - /// See also: GetMaskAndExpect and GetArgInfo for format of bitstring. - template - static constexpr auto GetMatcher(F fn) { - constexpr size_t args_count = mcl::parameter_count_v; - constexpr auto mask = std::get<0>(GetMaskAndExpect(bitstring)); - constexpr auto expect = std::get<1>(GetMaskAndExpect(bitstring)); - constexpr auto arg_masks = std::get<0>(GetArgInfo(bitstring)); - constexpr auto arg_shifts = std::get<1>(GetArgInfo(bitstring)); - const auto proxy_fn = VisitorCaller::Make(std::make_index_sequence(), fn, arg_masks, arg_shifts); - return MatcherT(mask, expect, proxy_fn); + template + static inline constexpr auto GetMatcherFunction(V& visitor, [[maybe_unused]] opcode_type instruction, ReturnType (V::*const fn)(Args...)) { + constexpr auto arg_masks = std::get<0>(GetArgInfo(bitstring)); + constexpr auto arg_shifts = std::get<1>(GetArgInfo(bitstring)); + return VisitorCaller::Invoke(std::index_sequence_for(), visitor, instruction, fn, arg_masks, arg_shifts); } }; -#define DYNARMIC_DECODER_GET_MATCHER(MatcherT, fn, name, bitstring) Decoder::detail::detail>::template GetMatcher(&V::fn) +#define DYNARMIC_DECODER_GET_MATCHER(MatcherT, fn, name, bitstring) Decoder::detail::detail>::GetMaskAndExpect(bitstring) + +#define DYNARMIC_DECODER_GET_MATCHER_FUNCTION(MatcherT, fn, name, bitstring) Decoder::detail::detail>::template GetMatcherFunction(visitor, instruction, &V::fn) } // namespace detail } // namespace Dynarmic::Decoder diff --git a/src/dynarmic/src/dynarmic/frontend/decoder/matcher.h b/src/dynarmic/src/dynarmic/frontend/decoder/matcher.h index 194f646ed2..49095f67e3 100644 --- a/src/dynarmic/src/dynarmic/frontend/decoder/matcher.h +++ b/src/dynarmic/src/dynarmic/frontend/decoder/matcher.h @@ -15,50 +15,41 @@ namespace Dynarmic::Decoder { /// Generic instruction handling construct. -/// @tparam Visitor An arbitrary visitor type that will be passed through -/// to the function being handled. This type must be the -/// type of the first parameter in a handler function. -/// @tparam OpcodeType Type representing an opcode. This must be the -/// type of the second parameter in a handler function. -template +/// @tparam V An arbitrary visitor type that will be passed through +/// to the function being handled. This type must be the +/// type of the first parameter in a handler function. +/// @tparam T Type representing an opcode. This must be the +/// type of the second parameter in a handler function. +template class Matcher { public: - using opcode_type = OpcodeType; - using visitor_type = Visitor; - using handler_return_type = typename Visitor::instruction_return_type; - using handler_function = std::function; - Matcher(opcode_type mask, opcode_type expected, handler_function func) - : mask{mask}, expected{expected}, fn{std::move(func)} {} + using opcode_type = T; + using visitor_type = V; - /// Gets the mask for this instruction. - inline opcode_type GetMask() const noexcept { + constexpr Matcher(T mask, T expected) noexcept + : mask{mask} + , expected{expected} + {} + + /// @brief Gets the mask for this instruction. + constexpr inline T GetMask() const noexcept { return mask; } - /// Gets the expected value after masking for this instruction. - inline opcode_type GetExpected() const noexcept { + /// @brief Gets the expected value after masking for this instruction. + constexpr inline T GetExpected() const noexcept { return expected; } - /// Tests to see if the given instruction is the instruction this matcher represents. + /// @brief Tests to see if the given instruction is the instruction this matcher represents. /// @param instruction The instruction to test /// @returns true if the given instruction matches. - inline bool Matches(opcode_type instruction) const noexcept { + constexpr inline bool Matches(T instruction) const noexcept { return (instruction & mask) == expected; } - /// Calls the corresponding instruction handler on visitor for this type of instruction. - /// @param v The visitor to use - /// @param instruction The instruction to decode. - inline handler_return_type call(Visitor& v, opcode_type instruction) const noexcept { - ASSERT(Matches(instruction)); - return fn(v, instruction); - } - -private: - opcode_type mask; - opcode_type expected; - handler_function fn; + T mask; + T expected; }; } // namespace Dynarmic::Decoder diff --git a/src/dynarmic/src/dynarmic/frontend/imm.h b/src/dynarmic/src/dynarmic/frontend/imm.h index 56fbcbda0e..f305b5bfc8 100644 --- a/src/dynarmic/src/dynarmic/frontend/imm.h +++ b/src/dynarmic/src/dynarmic/frontend/imm.h @@ -27,9 +27,8 @@ class Imm { public: static constexpr size_t bit_size = bit_size_; - explicit Imm(u32 value) - : value(value) { - ASSERT((mcl::bit::get_bits<0, bit_size - 1>(value) == value) && "More bits in value than expected"); + explicit Imm(u32 value) : value(value) { + DEBUG_ASSERT((mcl::bit::get_bits<0, bit_size - 1>(value) == value) && "More bits in value than expected"); } template diff --git a/src/dynarmic/tests/decoder_tests.cpp b/src/dynarmic/tests/decoder_tests.cpp index 2a6c0f6a4f..17ed2c0ce5 100644 --- a/src/dynarmic/tests/decoder_tests.cpp +++ b/src/dynarmic/tests/decoder_tests.cpp @@ -51,7 +51,7 @@ TEST_CASE("ASIMD Decoder: Ensure table order correctness", "[decode][a32][.]") { const bool iserr = is_decode_error(*iter, instruction); const auto alternative = std::find_if(table.cbegin(), iter, [instruction](const auto& m) { - return m.Matches(instruction); + return (instruction & mask) == expect; }); const bool altiserr = is_decode_error(*alternative, instruction); diff --git a/src/dynarmic/tests/print_info.cpp b/src/dynarmic/tests/print_info.cpp index 6d6109d849..988a8d294e 100644 --- a/src/dynarmic/tests/print_info.cpp +++ b/src/dynarmic/tests/print_info.cpp @@ -43,12 +43,12 @@ using namespace Dynarmic; std::string_view GetNameOfA32Instruction(u32 instruction) { - if (auto const vfp_decoder = A32::DecodeVFP(instruction)) - return *A32::GetNameVFP(instruction); - else if (auto const asimd_decoder = A32::DecodeASIMD(instruction)) - return *A32::GetNameASIMD(instruction); - else if (auto const decoder = A32::DecodeArm(instruction)) - return *A32::GetNameARM(instruction); + if (auto const vfp_decoder = A32::GetNameVFP(instruction)) + return *vfp_decoder; + else if (auto const asimd_decoder = A32::GetNameASIMD(instruction)) + return *asimd_decoder; + else if (auto const decoder = A32::GetNameArm(instruction)) + return *decoder; return ""; } From 672c21829b1126aeb1c1bfb867ac03e57e2e3c3a Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 9 May 2026 05:48:20 +0200 Subject: [PATCH 21/58] [core/hle/kernel] Remove redundant TLS load/stores, reuse computed segment+address instead (#3932) While originally for MSVC, this also should help clang/gcc not die trying to make codegen for the load/store of fields for the tls_data should help to reuse computed values instead of recomputing shit for no reason Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3932 Reviewed-by: MaranBr Reviewed-by: CamilleLaVey --- src/core/hle/kernel/kernel.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 129bda194a..5f88fa498f 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -372,17 +372,17 @@ struct KernelCore::Impl { } // Gets the dummy KThread for the caller, allocating a new one if this is the first time - KThread* GetHostDummyThread(KThread* existing_thread) { - if (tls_data.thread == nullptr) { + KThread* GetHostDummyThread(ThreadLocalData& t, KThread* existing_thread) { + if (t.thread == nullptr) { auto const initialize{[](KThread* thread) { ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess()); return thread; }}; - tls_data.raw_thread.emplace(system.Kernel()); - tls_data.thread = existing_thread ? existing_thread : initialize(&*tls_data.raw_thread); - ASSERT(tls_data.thread != nullptr); + t.raw_thread.emplace(system.Kernel()); + t.thread = existing_thread ? existing_thread : initialize(&*t.raw_thread); + ASSERT(t.thread != nullptr); } - return tls_data.thread; + return t.thread; } /// Registers a CPU core thread by allocating a host thread ID for it @@ -395,7 +395,7 @@ struct KernelCore::Impl { /// Registers a new host thread by allocating a host thread ID for it void RegisterHostThread(KThread* existing_thread) { - (void)GetHostDummyThread(existing_thread); + (void)GetHostDummyThread(tls_data, existing_thread); } [[nodiscard]] u32 GetCurrentHostThreadID() { @@ -419,9 +419,8 @@ struct KernelCore::Impl { } KThread* GetCurrentEmuThread() { - if (!tls_data.current_thread) - tls_data.current_thread = GetHostDummyThread(nullptr); - return tls_data.current_thread; + auto& t = tls_data; + return t.current_thread ? t.current_thread : (t.current_thread = GetHostDummyThread(t, nullptr)); } void SetCurrentEmuThread(KThread* thread) { From cad9db48861c5bea2a0dac47448dfb4e0d1f84d5 Mon Sep 17 00:00:00 2001 From: Eden CI Date: Sat, 9 May 2026 16:22:25 +0200 Subject: [PATCH 22/58] [dist, android] Update translations from Transifex for May 09 (#3941) Automatic translation update for May 09 Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3941 --- dist/languages/ar.ts | 26 ++++++++++++++++---------- dist/languages/ca.ts | 28 +++++++++++++++++----------- dist/languages/cs.ts | 26 ++++++++++++++++---------- dist/languages/da.ts | 26 ++++++++++++++++---------- dist/languages/de.ts | 26 ++++++++++++++++---------- dist/languages/el.ts | 26 ++++++++++++++++---------- dist/languages/es.ts | 26 ++++++++++++++++---------- dist/languages/fi.ts | 26 ++++++++++++++++---------- dist/languages/fr.ts | 26 ++++++++++++++++---------- dist/languages/hu.ts | 26 ++++++++++++++++---------- dist/languages/id.ts | 26 ++++++++++++++++---------- dist/languages/it.ts | 26 ++++++++++++++++---------- dist/languages/ja_JP.ts | 26 ++++++++++++++++---------- dist/languages/ko_KR.ts | 26 ++++++++++++++++---------- dist/languages/nb.ts | 26 ++++++++++++++++---------- dist/languages/nl.ts | 26 ++++++++++++++++---------- dist/languages/pl.ts | 26 ++++++++++++++++---------- dist/languages/pt_BR.ts | 26 ++++++++++++++++---------- dist/languages/pt_PT.ts | 26 ++++++++++++++++---------- dist/languages/ru_RU.ts | 26 ++++++++++++++++---------- dist/languages/sv.ts | 26 ++++++++++++++++---------- dist/languages/tr_TR.ts | 26 ++++++++++++++++---------- dist/languages/uk.ts | 26 ++++++++++++++++---------- dist/languages/vi.ts | 26 ++++++++++++++++---------- dist/languages/vi_VN.ts | 26 ++++++++++++++++---------- dist/languages/zh_CN.ts | 26 ++++++++++++++++---------- dist/languages/zh_TW.ts | 26 ++++++++++++++++---------- 27 files changed, 433 insertions(+), 271 deletions(-) diff --git a/dist/languages/ar.ts b/dist/languages/ar.ts index 4da378a1da..7b6a92dc6a 100644 --- a/dist/languages/ar.ts +++ b/dist/languages/ar.ts @@ -6038,47 +6038,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL غير متوفر! - + OpenGL shared contexts are not supported. OpenGL لا يتم دعم السياقات المشتركة - + Eden has not been compiled with OpenGL support. OpenGL لم يتم تجميع إيدن بدعم - - + + + Error while initializing OpenGL! OpenGL حدث خطأ أثناء تهيئة - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. أو قد لا يكون لديك أحدث برنامج تشغيل للرسومات OpenGL قد لا تدعم بطاقة الرسومات الخاصة بك - + Error while initializing OpenGL 4.6! OpenGL 4.6 حدث خطأ أثناء تهيئة - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 أو قد لا يكون لديك أحدث برنامج تشغيل للرسومات OpenGL 4.6 قد لا تدعم بطاقة الرسومات الخاصة بك.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 قد لا تدعم وحدة معالجة الرسومات لديك ملحقًا واحدًا أو أكثر من ملحقات OpenGL المطلوبة. يُرجى التأكد من تثبيت أحدث برنامج تشغيل للرسومات.<br><br>GL Renderer:<br>1%<br><br>إضافات غير مدعومة: <br>2% + + + This build doesn't have OpenGL support. + هذا الإصدار لا يدعم OpenGL. + GameList diff --git a/dist/languages/ca.ts b/dist/languages/ca.ts index 85b0c5c8ec..10db8a5e3a 100644 --- a/dist/languages/ca.ts +++ b/dist/languages/ca.ts @@ -494,7 +494,7 @@ This is mainly a debug option and shouldn't be disabled. Memory Layout - + Distribució de memòria @@ -5972,47 +5972,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL no disponible! - + OpenGL shared contexts are not supported. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Error al inicialitzar OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. La seva GPU no suporta OpenGL, o no té instal·lat els últims controladors gràfics. - + Error while initializing OpenGL 4.6! Error inicialitzant OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 La seva GPU no suporta OpenGL 4.6, o no té instal·lats els últims controladors gràfics.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 És possible que la seva GPU no suporti una o més extensions necessàries d'OpenGL. Si us plau, asseguris de tenir els últims controladors de la tarjeta gràfica.<br><br>GL Renderer:<br>%1<br><br>Extensions no suportades:<br>%2 + + + This build doesn't have OpenGL support. + Aquesta compilació no té suport per a OpenGL. + GameList diff --git a/dist/languages/cs.ts b/dist/languages/cs.ts index bf8ee5bee4..b7469b5d5c 100644 --- a/dist/languages/cs.ts +++ b/dist/languages/cs.ts @@ -5963,47 +5963,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL není k dispozici! - + OpenGL shared contexts are not supported. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Chyba při inicializaci OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Vaše grafická karta pravděpodobně nepodporuje OpenGL nebo nejsou nainstalovány nejnovější ovladače. - + Error while initializing OpenGL 4.6! Chyba při inicializaci OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Vaše grafická karta pravděpodobně nepodporuje OpenGL 4.6 nebo nejsou nainstalovány nejnovější ovladače.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Vaše grafická karta pravděpodobně nepodporuje jedno nebo více rozšíření OpenGL. Ujistěte se prosím, že jsou nainstalovány nejnovější ovladače.<br><br>GL Renderer:<br>%1<br><br>Nepodporované rozšíření:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/da.ts b/dist/languages/da.ts index 2805155565..91380077a2 100644 --- a/dist/languages/da.ts +++ b/dist/languages/da.ts @@ -5971,47 +5971,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! - + OpenGL shared contexts are not supported. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. - + Error while initializing OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/de.ts b/dist/languages/de.ts index a9797949aa..93652b117d 100644 --- a/dist/languages/de.ts +++ b/dist/languages/de.ts @@ -5986,47 +5986,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL nicht verfügbar! - + OpenGL shared contexts are not supported. Gemeinsame OpenGL-Kontexte werden nicht unterstützt. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Fehler beim Initialisieren von OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Deine Grafikkarte unterstützt kein OpenGL oder du hast nicht den neusten Treiber installiert. - + Error while initializing OpenGL 4.6! Fehler beim Initialisieren von OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Deine Grafikkarte unterstützt OpenGL 4.6 nicht, oder du benutzt nicht die neuste Treiberversion.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Deine Grafikkarte unterstützt anscheinend nicht eine oder mehrere von yuzu benötigten OpenGL-Erweiterungen. Bitte stelle sicher, dass du den neusten Grafiktreiber installiert hast.<br><br>GL Renderer:<br>%1<br><br>Nicht unterstützte Erweiterungen:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/el.ts b/dist/languages/el.ts index a70b386e96..ba849128fa 100644 --- a/dist/languages/el.ts +++ b/dist/languages/el.ts @@ -5962,47 +5962,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! Το OpenGL δεν είναι διαθέσιμο! - + OpenGL shared contexts are not supported. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Σφάλμα κατα την αρχικοποίηση του OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. - + Error while initializing OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/es.ts b/dist/languages/es.ts index 6ac892b4fb..115ca93dc6 100644 --- a/dist/languages/es.ts +++ b/dist/languages/es.ts @@ -6053,47 +6053,53 @@ Por favor, vaya a Configuración -> Sistema -> Red y selecciona una interf GRenderWindow - - + + OpenGL not available! ¡OpenGL no está disponible! - + OpenGL shared contexts are not supported. Los contextos compartidos de OpenGL no son compatibles. - + Eden has not been compiled with OpenGL support. Eden no ha sido compilado con soporte para OpenGL. - - + + + Error while initializing OpenGL! ¡Error al inicializar OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Tu GPU no soporta OpenGL, o no tienes instalados los últimos controladores gráficos. - + Error while initializing OpenGL 4.6! ¡Error al iniciar OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Tu GPU no soporta OpenGL 4.6, o no tienes instalado el último controlador de la tarjeta gráfica.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Es posible que la GPU no soporte una o más extensiones necesarias de OpenGL . Por favor, asegúrate de tener los últimos controladores de la tarjeta gráfica.<br><br>GL Renderer:<br>%1<br><br>Extensiones no soportadas:<br>%2 + + + This build doesn't have OpenGL support. + Esta compilación no tiene soporte para OpenGL. + GameList diff --git a/dist/languages/fi.ts b/dist/languages/fi.ts index 7efea10765..41917c09db 100644 --- a/dist/languages/fi.ts +++ b/dist/languages/fi.ts @@ -5940,47 +5940,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! openGL ei ole saatavilla! - + OpenGL shared contexts are not supported. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Virhe käynnistäessä OpenGL ydintä! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. - + Error while initializing OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/fr.ts b/dist/languages/fr.ts index dafb0064bd..d53b1902d4 100644 --- a/dist/languages/fr.ts +++ b/dist/languages/fr.ts @@ -6029,47 +6029,53 @@ Veuillez aller dans Configurer -> Système -> Réseau puis en choisir une. GRenderWindow - - + + OpenGL not available! OpenGL n'est pas disponible ! - + OpenGL shared contexts are not supported. Les contextes OpenGL partagés ne sont pas pris en charge. - + Eden has not been compiled with OpenGL support. Eden n'a pas été compilé avec le support OpenGL - - + + + Error while initializing OpenGL! Erreur lors de l'initialisation d'OpenGL ! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Votre GPU peut ne pas prendre en charge OpenGL, ou vous n'avez pas les derniers pilotes graphiques. - + Error while initializing OpenGL 4.6! Erreur lors de l'initialisation d'OpenGL 4.6 ! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Votre GPU peut ne pas prendre en charge OpenGL 4.6 ou vous ne disposez pas du dernier pilote graphique: %1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Votre GPU peut ne pas prendre en charge une ou plusieurs extensions OpenGL requises. Veuillez vous assurer que vous disposez du dernier pilote graphique.<br><br>GL Renderer :<br>%1<br><br>Extensions non prises en charge :<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/hu.ts b/dist/languages/hu.ts index d63f149eef..a9067946f0 100644 --- a/dist/languages/hu.ts +++ b/dist/languages/hu.ts @@ -5955,47 +5955,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL nem elérhető! - + OpenGL shared contexts are not supported. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Hiba történt az OpenGL inicializálása során! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Lehetséges, hogy a GPU-d nem támogatja az OpenGL-t, vagy nem a legfrissebb grafikus illesztőprogram van telepítve. - + Error while initializing OpenGL 4.6! Hiba történt az OpenGL 4.6 inicializálása során! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Lehetséges, hogy a GPU-d nem támogatja az OpenGL 4.6-ot, vagy nem a legfrissebb grafikus illesztőprogram van telepítve.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Előfordulhat, hogy a GPU-d nem támogat egy vagy több szükséges OpenGL kiterjesztést. Győződj meg róla, hogy a legújabb videokártya-illesztőprogramot használod.<br><br>GL Renderer:<br>%1<br><br>Nem támogatott kiterjesztések:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/id.ts b/dist/languages/id.ts index 3fd423e6f6..d759c99d70 100644 --- a/dist/languages/id.ts +++ b/dist/languages/id.ts @@ -5991,47 +5991,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL tidak tersedia! - + OpenGL shared contexts are not supported. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Terjadi kesalahan menginisialisasi OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. VGA anda mungkin tidak mendukung OpenGL, atau anda tidak memiliki pemacu piranti (driver) grafis terbaharu. - + Error while initializing OpenGL 4.6! Terjadi kesalahan menginisialisasi OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 VGA anda mungkin tidak mendukung OpenGL 4.6, atau anda tidak memiliki pemacu piranti (driver) grafis terbaharu.<br><br>Pemuat GL:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 VGA anda mungkin tidak mendukung satu atau lebih ekstensi OpenGL. Mohon pastikan bahwa anda memiliki pemacu piranti (driver) grafis terbaharu.<br><br>Pemuat GL:<br>%1<br><br>Ekstensi yang tidak didukung:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/it.ts b/dist/languages/it.ts index 881fce570f..d85159bdc2 100644 --- a/dist/languages/it.ts +++ b/dist/languages/it.ts @@ -6052,47 +6052,53 @@ Vai su Configura -> Sistema -> Rete e selezionane una. GRenderWindow - - + + OpenGL not available! OpenGL non disponibile! - + OpenGL shared contexts are not supported. Gli shared context di OpenGL non sono supportati. - + Eden has not been compiled with OpenGL support. Eden non è stato compilato con il supporto a OpenGL. - - + + + Error while initializing OpenGL! Errore durante l'inizializzazione di OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. La tua GPU potrebbe non supportare OpenGL, o non hai installato l'ultima versione dei driver video. - + Error while initializing OpenGL 4.6! Errore durante l'inizializzazione di OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 La tua GPU potrebbe non supportare OpenGL 4.6, o non hai installato l'ultima versione dei driver video.<br><br>Renderer GL:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 La tua GPU potrebbe non supportare una o più estensioni OpenGL richieste. Assicurati di aver installato i driver video più recenti.<br><br>Renderer GL:<br>%1<br><br>Estensioni non supportate:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/ja_JP.ts b/dist/languages/ja_JP.ts index 1c743b6f62..c1ab881dde 100644 --- a/dist/languages/ja_JP.ts +++ b/dist/languages/ja_JP.ts @@ -5978,47 +5978,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGLは使用できません! - + OpenGL shared contexts are not supported. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! OpenGL初期化エラー - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. GPUがOpenGLをサポートしていないか、グラフィックスドライバーが最新ではありません。 - + Error while initializing OpenGL 4.6! OpenGL4.6初期化エラー! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 GPUがOpenGL4.6をサポートしていないか、グラフィックスドライバーが最新ではありません。<br><br>GL レンダラ:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 GPUが1つ以上の必要なOpenGL拡張機能をサポートしていない可能性があります。最新のグラフィックドライバを使用していることを確認してください。<br><br>GL レンダラ:<br>%1<br><br>サポートされていない拡張機能:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/ko_KR.ts b/dist/languages/ko_KR.ts index c9fa32ccac..590a031a80 100644 --- a/dist/languages/ko_KR.ts +++ b/dist/languages/ko_KR.ts @@ -5976,47 +5976,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL을 사용할 수 없습니다! - + OpenGL shared contexts are not supported. OpenGL 공유 컨텍스트는 지원되지 않습니다. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! OpenGL을 초기화하는 동안 오류가 발생했습니다! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. 사용하시는 GPU가 OpenGL을 지원하지 않거나, 최신 그래픽 드라이버가 설치되어 있지 않습니다. - + Error while initializing OpenGL 4.6! OpenGL 4.6 초기화 중 오류 발생! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 사용하시는 GPU가 OpenGL 4.6을 지원하지 않거나 최신 그래픽 드라이버가 설치되어 있지 않습니다. <br><br>GL 렌더링 장치:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 사용하시는 GPU가 1개 이상의 OpenGL 확장 기능을 지원하지 않습니다. 최신 그래픽 드라이버가 설치되어 있는지 확인하세요. <br><br>GL 렌더링 장치:<br>%1<br><br>지원하지 않는 확장 기능:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/nb.ts b/dist/languages/nb.ts index bdfc81b0c9..1c876beafc 100644 --- a/dist/languages/nb.ts +++ b/dist/languages/nb.ts @@ -5975,47 +5975,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL ikke tilgjengelig! - + OpenGL shared contexts are not supported. Delte OpenGL-kontekster støttes ikke. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Feil under initialisering av OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Det kan hende at GPU-en din ikke støtter OpenGL, eller at du ikke har den nyeste grafikkdriveren. - + Error while initializing OpenGL 4.6! Feil under initialisering av OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Det kan hende at GPU-en din ikke støtter OpenGL 4.6, eller at du ikke har den nyeste grafikkdriveren.<br><br>GL-renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Det kan hende at GPU-en din ikke støtter én eller flere nødvendige OpenGL-utvidelser. Vennligst sørg for at du har den nyeste grafikkdriveren.<br><br>GL-renderer: <br>%1<br><br>Ikke-støttede utvidelser:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/nl.ts b/dist/languages/nl.ts index f477915014..81d70da92c 100644 --- a/dist/languages/nl.ts +++ b/dist/languages/nl.ts @@ -5973,47 +5973,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL niet beschikbaar! - + OpenGL shared contexts are not supported. OpenGL gedeelde contexten worden niet ondersteund. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Fout tijdens het initialiseren van OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Je GPU ondersteunt mogelijk geen OpenGL, of je hebt niet de laatste grafische stuurprogramma. - + Error while initializing OpenGL 4.6! Fout tijdens het initialiseren van OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Je GPU ondersteunt mogelijk OpenGL 4.6 niet, of je hebt niet het laatste grafische stuurprogramma.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Je GPU ondersteunt mogelijk een of meer vereiste OpenGL-extensies niet. Zorg ervoor dat je het laatste grafische stuurprogramma hebt.<br><br>GL Renderer:<br>%1<br><br>Ondersteunde extensies:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/pl.ts b/dist/languages/pl.ts index a107dcffdf..ef2078c554 100644 --- a/dist/languages/pl.ts +++ b/dist/languages/pl.ts @@ -6041,47 +6041,53 @@ Przejdź do sekcji Konfiguracja -> System -> Sieć i dokonaj wyboru. GRenderWindow - - + + OpenGL not available! OpenGL niedostępny! - + OpenGL shared contexts are not supported. Współdzielone konteksty OpenGL nie są obsługiwane. - + Eden has not been compiled with OpenGL support. Eden nie został skompilowany z obsługą OpenGL. - - + + + Error while initializing OpenGL! Błąd podczas inicjowania OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Twoja karta graficzna może nie obsługiwać OpenGL lub nie masz najnowszych sterowników karty graficznej. - + Error while initializing OpenGL 4.6! Błąd podczas inicjowania OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Twoja karta graficzna może nie obsługiwać OpenGL 4.6 lub nie masz najnowszych sterowników karty graficznej.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Twoja karta graficzna może nie obsługiwać co najmniej jednego wymaganego rozszerzenia OpenGL. Upewnij się, że masz najnowsze sterowniki karty graficznej<br><br>GL Renderer:<br>%1<br><br>Nieobsługiwane rozszerzenia:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/pt_BR.ts b/dist/languages/pt_BR.ts index 440421e998..aa64808086 100644 --- a/dist/languages/pt_BR.ts +++ b/dist/languages/pt_BR.ts @@ -6028,47 +6028,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL não está disponível! - + OpenGL shared contexts are not supported. Shared contexts do OpenGL não são suportados. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Erro ao inicializar OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. O seu GPU pode não suportar OpenGL, ou não tem os drivers gráficos mais recentes. - + Error while initializing OpenGL 4.6! Erro ao inicializar o OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 O teu GPU pode não suportar OpenGL 4.6, ou não tem os drivers gráficos mais recentes. - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Sua GPU pode não suportar uma ou mais extensões necessárias do OpenGL. Verifique se você possui a última versão dos drivers gráficos.<br><br>Renderizador GL:<br>%1<br><br>Extensões não suportadas:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/pt_PT.ts b/dist/languages/pt_PT.ts index 1fd356238b..1e535c5e92 100644 --- a/dist/languages/pt_PT.ts +++ b/dist/languages/pt_PT.ts @@ -5976,47 +5976,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL não está disponível! - + OpenGL shared contexts are not supported. Shared contexts do OpenGL não são suportados. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Erro ao inicializar OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. O seu GPU pode não suportar OpenGL, ou não tem os drivers gráficos mais recentes. - + Error while initializing OpenGL 4.6! Erro ao inicializar o OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 O teu GPU pode não suportar OpenGL 4.6, ou não tem os drivers gráficos mais recentes. - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Sua GPU pode não suportar uma ou mais extensões necessárias do OpenGL. Verifique se você possui a última versão dos drivers gráficos.<br><br>Renderizador GL:<br>%1<br><br>Extensões não suportadas:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/ru_RU.ts b/dist/languages/ru_RU.ts index 56d893d688..063804860b 100644 --- a/dist/languages/ru_RU.ts +++ b/dist/languages/ru_RU.ts @@ -6056,47 +6056,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL не доступен! - + OpenGL shared contexts are not supported. Общие контексты OpenGL не поддерживаются. - + Eden has not been compiled with OpenGL support. Eden не был скомпилирован с поддержкой OpenGL. - - + + + Error while initializing OpenGL! Ошибка при инициализации OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Ваш ГП может не поддерживать OpenGL, или у вас установлен устаревший графический драйвер. - + Error while initializing OpenGL 4.6! Ошибка при инициализации OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Ваш ГП может не поддерживать OpenGL 4.6, или у вас установлен устаревший графический драйвер.<br><br>Рендерер GL:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Ваш ГП может не поддерживать одно или несколько требуемых расширений OpenGL. Пожалуйста, убедитесь в том, что у вас установлен последний графический драйвер.<br><br>Рендерер GL:<br>%1<br><br>Неподдерживаемые расширения:<br>%2 + + + This build doesn't have OpenGL support. + В этой сборке отсутствует поддержка OpenGL. + GameList diff --git a/dist/languages/sv.ts b/dist/languages/sv.ts index 6a04aacd39..3865e56ee0 100644 --- a/dist/languages/sv.ts +++ b/dist/languages/sv.ts @@ -6063,47 +6063,53 @@ Gå till Konfigurera -> System -> Nätverk och gör ett val. GRenderWindow - - + + OpenGL not available! OpenGL är inte tillgängligt! - + OpenGL shared contexts are not supported. Delade OpenGL-kontexter stöds inte. - + Eden has not been compiled with OpenGL support. Eden har inte kompilerats med OpenGL-stöd. - - + + + Error while initializing OpenGL! Fel vid initiering av OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Din GPU kanske inte stöder OpenGL, eller så har du inte den senaste grafikdrivrutinen. - + Error while initializing OpenGL 4.6! Fel vid initiering av OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Din GPU kanske inte stöder OpenGL 4.6, eller så har du inte den senaste grafikdrivrutinen.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Din GPU kanske inte stöder ett eller flera av de nödvändiga OpenGL-tilläggen. Se till att du har den senaste grafikdrivrutinen.<br><br>GL Renderer:<br>%1<br><br>Tillägg som inte stöds:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/tr_TR.ts b/dist/languages/tr_TR.ts index eec5e5f2af..5cc62a47d8 100644 --- a/dist/languages/tr_TR.ts +++ b/dist/languages/tr_TR.ts @@ -6004,47 +6004,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL kullanıma uygun değil! - + OpenGL shared contexts are not supported. OpenGL paylaşılan bağlam desteklenmiyor. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! OpenGl başlatılırken bir hata oluştu! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. GPU'nuz OpenGL desteklemiyor veya güncel bir grafik sürücüsüne sahip değilsiniz. - + Error while initializing OpenGL 4.6! OpenGl 4.6 başlatılırken bir hata oluştu! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 GPU'nuz OpenGL 4.6'yı desteklemiyor veya güncel bir grafik sürücüsüne sahip değilsiniz.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 GPU'nuz gereken bir yada daha fazla OpenGL eklentisini desteklemiyor Lütfen güncel bir grafik sürücüsüne sahip olduğunuzdan emin olun.<br><br>GL Renderer:<br>%1<br><br> Desteklenmeyen Eklentiler:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/uk.ts b/dist/languages/uk.ts index cf69e3dac5..fe0651bdb1 100644 --- a/dist/languages/uk.ts +++ b/dist/languages/uk.ts @@ -6058,47 +6058,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL недоступний! - + OpenGL shared contexts are not supported. Спільні контексти OpenGL не підтримуються. - + Eden has not been compiled with OpenGL support. Eden не скомпільовано з підтримкою OpenGL. - - + + + Error while initializing OpenGL! Помилка під час ініціалізації OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. Ваш ГП може не підтримувати OpenGL або у вас встановлено застарілий графічний драйвер. - + Error while initializing OpenGL 4.6! Помилка під час ініціалізації OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 Ваш ГП може не підтримувати OpenGL 4.6 або у вас встановлено застарілий графічний драйвер.<br><br>Візуалізатор GL:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 Ваш ГП може не підтримувати одне або кілька розширень, необхідних для OpenGL. Переконайтеся, що у вас встановлено останній графічний драйвер.<br><br>Візуалізатор GL:<br>%1<br><br>Непідтримувані розширення:<br>%2 + + + This build doesn't have OpenGL support. + Ця збірка не підтримує OpenGL. + GameList diff --git a/dist/languages/vi.ts b/dist/languages/vi.ts index fc59c32ef4..5cbda3c24f 100644 --- a/dist/languages/vi.ts +++ b/dist/languages/vi.ts @@ -5976,47 +5976,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL không khả dụng! - + OpenGL shared contexts are not supported. Các ngữ cảnh OpenGL chung không được hỗ trợ. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Lỗi khi khởi tạo OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. GPU của bạn có thể không hỗ trợ OpenGL, hoặc bạn không có driver đồ hoạ mới nhất. - + Error while initializing OpenGL 4.6! Lỗi khi khởi tạo OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 GPU của bạn có thể không hỗ trợ OpenGL 4.6, hoặc bạn không có driver đồ hoạ mới nhất.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 GPU của bạn có thể không hỗ trợ một hoặc nhiều tiện ích OpenGL cần thiết. Vui lòng đảm bảo bạn có driver đồ hoạ mới nhất.<br><br>GL Renderer:<br>%1<br><br>Tiện ích không hỗ trợ:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/vi_VN.ts b/dist/languages/vi_VN.ts index 62b8839175..8fa5494c73 100644 --- a/dist/languages/vi_VN.ts +++ b/dist/languages/vi_VN.ts @@ -5976,47 +5976,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! Không có sẵn OpenGL! - + OpenGL shared contexts are not supported. Các ngữ cảnh OpenGL chung không được hỗ trợ. - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! Đã xảy ra lỗi khi khởi tạo OpenGL! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. GPU của bạn có thể không hỗ trợ OpenGL, hoặc bạn không có driver đồ hoạ mới nhất. - + Error while initializing OpenGL 4.6! Lỗi khi khởi tạo OpenGL 4.6! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 GPU của bạn có thể không hỗ trợ OpenGL 4.6, hoặc bạn không có driver đồ hoạ mới nhất.<br><br>GL Renderer:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 GPU của bạn có thể không hỗ trợ một hoặc nhiều tiện ích OpenGL cần thiết. Vui lòng đảm bảo bạn có driver đồ hoạ mới nhất.<br><br>GL Renderer:<br>%1<br><br>Tiện ích không hỗ trợ:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/zh_CN.ts b/dist/languages/zh_CN.ts index e87c276484..aa5cda0fcc 100644 --- a/dist/languages/zh_CN.ts +++ b/dist/languages/zh_CN.ts @@ -6044,47 +6044,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! OpenGL 模式不可用! - + OpenGL shared contexts are not supported. 不支持 OpenGL 共享上下文。 - + Eden has not been compiled with OpenGL support. Eden 尚未编译为支持 OpenGL。 - - + + + Error while initializing OpenGL! 初始化 OpenGL 时出错! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. 您的 GPU 可能不支持 OpenGL ,或者您没有安装最新的显卡驱动。 - + Error while initializing OpenGL 4.6! 初始化 OpenGL 4.6 时出错! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 您的 GPU 可能不支持 OpenGL 4.6 ,或者您没有安装最新的显卡驱动。<br><br>GL 渲染器:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 您的 GPU 可能不支持某些必需的 OpenGL 扩展。请确保您已经安装最新的显卡驱动。<br><br>GL 渲染器:<br>%1<br><br>不支持的扩展:<br>%2 + + + This build doesn't have OpenGL support. + + GameList diff --git a/dist/languages/zh_TW.ts b/dist/languages/zh_TW.ts index be87e5c11b..b09469591b 100644 --- a/dist/languages/zh_TW.ts +++ b/dist/languages/zh_TW.ts @@ -6003,47 +6003,53 @@ Please go to Configure -> System -> Network and make a selection. GRenderWindow - - + + OpenGL not available! 無法使用 OpenGL 模式! - + OpenGL shared contexts are not supported. 不支援 OpenGL 共用的上下文。 - + Eden has not been compiled with OpenGL support. - - + + + Error while initializing OpenGL! 初始化 OpenGL 時發生錯誤! - + Your GPU may not support OpenGL, or you do not have the latest graphics driver. 您的 GPU 可能不支援 OpenGL,或是未安裝最新的圖形驅動程式 - + Error while initializing OpenGL 4.6! 初始化 OpenGL 4.6 時發生錯誤! - + Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 您的 GPU 可能不支援 OpenGL 4.6,或是未安裝最新的圖形驅動程式<br><br>GL 渲染器:<br>%1 - + Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported extensions:<br>%2 您的 GPU 可能不支援某些必需的 OpenGL 功能。請確保您已安裝最新的圖形驅動程式。<br><br>GL 渲染器:<br>%1<br><br>不支援的功能:<br>%2 + + + This build doesn't have OpenGL support. + + GameList From 86f2f0bc36845ac45de315d9ba78c569b62d866a Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 9 May 2026 16:26:17 +0200 Subject: [PATCH 23/58] [*] Re-fix clang-cl building (#3940) Signed-off-by: lizzie Co-authored-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3940 Reviewed-by: crueter Reviewed-by: MaranBr --- CMakeLists.txt | 44 +++++++++++-------- .../demangle/llvm/Demangle/ItaniumDemangle.h | 4 +- externals/demangle/llvm/Demangle/Utility.h | 4 +- externals/tz/tz/tz.cpp | 11 +++-- externals/tz/tz/tz.h | 11 +++-- src/CMakeLists.txt | 2 +- src/video_core/buffer_cache/buffer_cache.h | 4 +- .../renderer_vulkan/vk_query_cache.cpp | 4 +- 8 files changed, 48 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1142585b6d..32e873f009 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,6 +169,31 @@ if (MSVC AND NOT CXX_CLANG) set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} /W3 /WX-") endif() +# Set runtime library to MD/MDd for all configurations +if(MSVC) + if (YUZU_USE_BUNDLED_QT AND ARCHITECTURE_arm64) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + set(libflag MT) + else() + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") + set(libflag MD) + endif() + + # Force all projects (including external dependencies) to use the same runtime + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /${libflag}") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /${libflag}d") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /${libflag}") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /${libflag}d") + + # Add this to ensure Cubeb uses the same runtime + add_compile_options( + $<$:$<$:/${libflag}d>> + $<$:$<$:/${libflag}>> + $<$:$<$:/${libflag}>> + $<$:$<$:/${libflag}>> + ) +endif() + # 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 "NOT MSVC;NOT ANDROID" OFF) cmake_dependent_option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "NOT ANDROID" OFF) @@ -688,25 +713,6 @@ if (MSVC AND CXX_CLANG) link_libraries(llvm-mingw-runtime) endif() -# Set runtime library to MD/MDd for all configurations -if(MSVC) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") - - # Force all projects (including external dependencies) to use the same runtime - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MD") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MDd") - - # Add this to ensure Cubeb uses the same runtime - add_compile_options( - $<$:/MDd> - $<$:/MD> - $<$:/MD> - $<$:/MD> - ) -endif() - add_subdirectory(src) # Set yuzu project or yuzu-cmd project as default StartUp Project in Visual Studio depending on whether QT is enabled or not diff --git a/externals/demangle/llvm/Demangle/ItaniumDemangle.h b/externals/demangle/llvm/Demangle/ItaniumDemangle.h index 0dc3d73372..a2bac5d735 100644 --- a/externals/demangle/llvm/Demangle/ItaniumDemangle.h +++ b/externals/demangle/llvm/Demangle/ItaniumDemangle.h @@ -1259,7 +1259,7 @@ class ParameterPack final : public Node { // Setup OutputBuffer for a pack expansion, unless we're already expanding // one. void initializePackExpansion(OutputBuffer &OB) const { - if (OB.CurrentPackMax == std::numeric_limits::max()) { + if (OB.CurrentPackMax == (std::numeric_limits::max)()) { OB.CurrentPackMax = static_cast(Data.size()); OB.CurrentPackIndex = 0; } @@ -1353,7 +1353,7 @@ public: const Node *getChild() const { return Child; } void printLeft(OutputBuffer &OB) const override { - constexpr unsigned Max = std::numeric_limits::max(); + constexpr unsigned Max = (std::numeric_limits::max)(); ScopedOverride SavePackIdx(OB.CurrentPackIndex, Max); ScopedOverride SavePackMax(OB.CurrentPackMax, Max); size_t StreamPos = OB.getCurrentPosition(); diff --git a/externals/demangle/llvm/Demangle/Utility.h b/externals/demangle/llvm/Demangle/Utility.h index 30dfbfc8dc..0d2e613ea9 100644 --- a/externals/demangle/llvm/Demangle/Utility.h +++ b/externals/demangle/llvm/Demangle/Utility.h @@ -88,8 +88,8 @@ public: /// If a ParameterPackExpansion (or similar type) is encountered, the offset /// into the pack that we're currently printing. - unsigned CurrentPackIndex = std::numeric_limits::max(); - unsigned CurrentPackMax = std::numeric_limits::max(); + unsigned CurrentPackIndex = (std::numeric_limits::max)(); + unsigned CurrentPackMax = (std::numeric_limits::max)(); /// When zero, we're printing template args and '>' needs to be parenthesized. /// Use a counter so we can simply increment inside parentheses. diff --git a/externals/tz/tz/tz.cpp b/externals/tz/tz/tz.cpp index 04fa6cc8a9..3269d9cc1e 100644 --- a/externals/tz/tz/tz.cpp +++ b/externals/tz/tz/tz.cpp @@ -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-FileCopyrightText: 1996 Arthur David Olson // SPDX-License-Identifier: BSD-2-Clause @@ -466,8 +469,8 @@ CalendarTimeInternal* timesub(const time_t* timep, s64 offset, const Rule* sp, int signed_y = static_cast(y); tmp->tm_year = signed_y - TM_YEAR_BASE; } - else if ((!std::is_signed_v || std::numeric_limits::min() + TM_YEAR_BASE <= y) && - y - TM_YEAR_BASE <= std::numeric_limits::max()) { + else if ((!std::is_signed_v || (std::numeric_limits::min)() + TM_YEAR_BASE <= y) && + y - TM_YEAR_BASE <= (std::numeric_limits::max)()) { tmp->tm_year = static_cast(y - TM_YEAR_BASE); } else { @@ -558,8 +561,8 @@ CalendarTimeInternal* localsub(Rule const* sp, time_t const* timep, s64 setname, else { newy += years; } - if (!(std::numeric_limits::min() <= newy && - newy <= std::numeric_limits::max())) { + if (!((std::numeric_limits::min)() <= newy && + newy <= (std::numeric_limits::max)())) { return nullptr; } result->tm_year = static_cast(newy); diff --git a/externals/tz/tz/tz.h b/externals/tz/tz/tz.h index dae4459bcb..e70092a987 100644 --- a/externals/tz/tz/tz.h +++ b/externals/tz/tz/tz.h @@ -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-FileCopyrightText: 1996 Arthur David Olson // SPDX-License-Identifier: BSD-2-Clause @@ -26,10 +29,10 @@ constexpr size_t TZ_MAX_CHARS = 50; constexpr size_t MY_TZNAME_MAX = 255; constexpr size_t TZNAME_MAXIMUM = 255; constexpr size_t TZ_MAX_LEAPS = 50; -constexpr s64 TIME_T_MAX = std::numeric_limits::max(); -constexpr s64 TIME_T_MIN = std::numeric_limits::min(); +constexpr s64 TIME_T_MAX = (std::numeric_limits::max)(); +constexpr s64 TIME_T_MIN = (std::numeric_limits::min)(); constexpr size_t CHARS_EXTRA = 3; -constexpr size_t MAX_ZONE_CHARS = std::max(TZ_MAX_CHARS + CHARS_EXTRA, sizeof("UTC")); +constexpr size_t MAX_ZONE_CHARS = (std::max)(TZ_MAX_CHARS + CHARS_EXTRA, sizeof("UTC")); constexpr size_t MAX_TZNAME_CHARS = 2 * (MY_TZNAME_MAX + 1); struct ttinfo { @@ -51,7 +54,7 @@ struct Rule { std::array ats; std::array types; std::array ttis; - std::array chars; + std::array chars; s32 defaulttype; std::array padding1; }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ec064a0e34..48544aeaec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -185,7 +185,7 @@ else() add_compile_definitions(_FILE_OFFSET_BITS=64) endif() - if (YUZU_STATIC_BUILD AND NOT APPLE) + if (YUZU_STATIC_BUILD AND NOT APPLE AND NOT MSVC) add_compile_options(-static) # yuzu-cmd requires us to explicitly link libpthread, libgcc, and libstdc++ as static diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index eaa6912f0d..60e0e8449b 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -811,7 +811,7 @@ void BufferCache

::BindHostVertexBuffers() { auto& flags = maxwell3d->dirty.flags; u32 enabled_mask = enabled_vertex_buffers_mask; HostBindings bindings{}; - u32 last_index = std::numeric_limits::max(); + u32 last_index = (std::numeric_limits::max)(); const auto flush_bindings = [&]() { if (bindings.buffers.empty()) { return; @@ -819,7 +819,7 @@ void BufferCache

::BindHostVertexBuffers() { bindings.max_index = bindings.min_index + static_cast(bindings.buffers.size()); runtime.BindVertexBuffers(bindings); bindings = HostBindings{}; - last_index = std::numeric_limits::max(); + last_index = (std::numeric_limits::max)(); }; while (enabled_mask != 0) { const u32 index = std::countr_zero(enabled_mask); diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 9543c65bd4..98062a78dc 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp @@ -951,7 +951,7 @@ private: runtime.View3DRegs([this](Maxwell3D& maxwell3d) { buffers_count = 0; out_topology = maxwell3d.draw_manager.draw_state.topology; - patch_vertices = std::max(maxwell3d.regs.patch_vertices, 1U); + patch_vertices = (std::max)(maxwell3d.regs.patch_vertices, 1U); if (out_topology == Maxwell3D::Regs::PrimitiveTopology::Patches) { switch (maxwell3d.regs.tessellation.params.output_primitives.Value()) { case Maxwell3D::Regs::Tessellation::OutputPrimitives::Points: @@ -1145,7 +1145,7 @@ public: } new_query->stride = 1; runtime.View3DRegs([new_query, subreport](Maxwell3D& maxwell3d) { - new_query->patch_vertices = std::max(maxwell3d.regs.patch_vertices, 1U); + new_query->patch_vertices = (std::max)(maxwell3d.regs.patch_vertices, 1U); for (size_t i = 0; i < Maxwell3D::Regs::NumTransformFeedbackBuffers; i++) { const auto& tf = maxwell3d.regs.transform_feedback; if (tf.buffers[i].enable == 0) { From 732fee2e857414548707c7f9906d1e6eab7c205a Mon Sep 17 00:00:00 2001 From: John Date: Sat, 9 May 2026 23:49:14 +0200 Subject: [PATCH 24/58] Add Enable Legacy Rescale Pass to Android (#3851) Testing: Luigi Mansion 3 artifact lines also happen on android. Toggle existed on every platform but android. It works on Android and also removes the artifact lines that also happen on intel and amd gpus. A testing PR until #3665 Co-authored-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3851 Reviewed-by: CamilleLaVey --- .../yuzu_emu/features/settings/model/BooleanSetting.kt | 1 + .../features/settings/model/view/SettingsItem.kt | 7 +++++++ .../features/settings/ui/SettingsFragmentPresenter.kt | 1 + src/android/app/src/main/res/values/strings.xml | 2 ++ src/common/settings.h | 9 +++++++-- 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index e482725196..eccf0549e7 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -18,6 +18,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"), FIX_BLOOM_EFFECTS("fix_bloom_effects"), EMULATE_BGR565("emulate_bgr565"), + RESCALE_HACK("rescale_hack"), CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"), USE_DOCKED_MODE("use_docked_mode"), USE_AUTO_STUB("use_auto_stub"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index db2edba1b9..3a5f466f07 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -747,6 +747,13 @@ abstract class SettingsItem( descriptionId = R.string.fix_bloom_effects_description ) ) + put( + SwitchSetting( + BooleanSetting.RESCALE_HACK, + titleId = R.string.rescale_hack, + descriptionId = R.string.rescale_hack_description + ) + ) put( SwitchSetting( BooleanSetting.EMULATE_BGR565, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index ccbe808cf6..9f0e409cf4 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -293,6 +293,7 @@ class SettingsFragmentPresenter( add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key) add(BooleanSetting.FIX_BLOOM_EFFECTS.key) add(BooleanSetting.EMULATE_BGR565.key) + add(BooleanSetting.RESCALE_HACK.key) add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key) add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key) add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key) diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index d143a12f4e..7cdce5339f 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -511,6 +511,8 @@ Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games. Emulate BGR565 Fixes problems with inverted colors in games or strange artifacts or strange shadows. + Enable Legacy Rescale Pass + Enables a legacy handling for the rescale configuration pass for games by using a quick rescale path Use asynchronous shaders Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches. GPU Unswizzle Settings diff --git a/src/common/settings.h b/src/common/settings.h index 9749a8df40..d9e1f09dcc 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -554,8 +554,13 @@ struct Values { SwitchableSetting emulate_bgr565{linkage, false, "emulate_bgr565", Category::RendererHacks}; - SwitchableSetting rescale_hack{linkage, false, "rescale_hack", - Category::RendererHacks}; + SwitchableSetting rescale_hack{linkage, +#ifdef __ANDROID__ + true, +#else + false, +#endif + "rescale_hack", Category::RendererHacks}; SwitchableSetting use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders", Category::RendererHacks}; From afe92c5bed297b5ee51ce462f645bf3e06cfd1a2 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sun, 10 May 2026 05:36:58 +0200 Subject: [PATCH 25/58] [dist] new 1st anniversary icon (#3942) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3942 Reviewed-by: CamilleLaVey Reviewed-by: MaranBr --- dist/dev.eden_emu.eden.svg | 207 ++++++++----- dist/eden.bmp | Bin 262282 -> 262282 bytes dist/eden.ico | Bin 343119 -> 569494 bytes dist/icon_variations/1an.svg | 289 ++++++++++++++++++ dist/icon_variations/1an_bgcolor | 1 + dist/qt_themes/default/icons/256x256/eden.png | Bin 35682 -> 27621 bytes .../res/drawable/ic_launcher_foreground.png | Bin 134584 -> 112114 bytes .../app/src/main/res/drawable/ic_yuzu.png | Bin 57729 -> 45725 bytes .../src/main/res/drawable/ic_yuzu_splash.png | Bin 52424 -> 41366 bytes .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 14132 -> 14095 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 9643 -> 9533 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 24263 -> 24213 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 35659 -> 35163 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 68697 -> 62469 bytes .../app/src/main/res/values/colors.xml | 2 +- 15 files changed, 424 insertions(+), 75 deletions(-) create mode 100644 dist/icon_variations/1an.svg create mode 100644 dist/icon_variations/1an_bgcolor diff --git a/dist/dev.eden_emu.eden.svg b/dist/dev.eden_emu.eden.svg index f88b52f625..df206b43af 100644 --- a/dist/dev.eden_emu.eden.svg +++ b/dist/dev.eden_emu.eden.svg @@ -6,8 +6,8 @@ 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)" + sodipodi:docname="1stanni.svg" + inkscape:version="1.4.3 (0d15f75042, 2025-12-25)" inkscape:export-filename="base.svg.2026_01_12_14_43_47.0.svg" inkscape:export-xdpi="96" inkscape:export-ydpi="96" @@ -19,36 +19,34 @@ + id="stop34" /> - + style="stop-color:#ffd700;stop-opacity:0.48031053;" + offset="1" + id="stop35" /> + + id="stop21" /> - + style="stop-color:#830091;stop-opacity:1;" + offset="1" + id="stop22" /> - - - - - - @@ -165,16 +136,6 @@ inkscape:label="Circle" r="191.89999" /> - @@ -187,14 +148,106 @@ + y2="512" + gradientUnits="userSpaceOnUse" /> + + + + + + + + + + + + + + + + + + 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 literal 343119 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 L&!sJEx%2~|uw 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 diff --git a/dist/icon_variations/1an.svg b/dist/icon_variations/1an.svg new file mode 100644 index 0000000000..df206b43af --- /dev/null +++ b/dist/icon_variations/1an.svg @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dist/icon_variations/1an_bgcolor b/dist/icon_variations/1an_bgcolor new file mode 100644 index 0000000000..a47436df7f --- /dev/null +++ b/dist/icon_variations/1an_bgcolor @@ -0,0 +1 @@ +#ffd700 diff --git a/dist/qt_themes/default/icons/256x256/eden.png b/dist/qt_themes/default/icons/256x256/eden.png index 3c4bd566a10abb72cb76654324631a170d6fa471..d0b02580dfe1b799ecb0e45211012831d88ffc72 100644 GIT binary patch literal 27621 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 literal 35682 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

rXS+Gj& zYusf~j`bBlqNB9O3bOjPP?3}0))qVyzI@Dclf;8vY{f&J6yj|UAC8m*DU!Z-boR&o zU#FDa61lxeS)2+RT_HEWEKbwi{g?zoX5Lm;QxG@7#97Otr} zO@o6>5U7zCM4vf)nQiyIOX@o~C8OS7s`XquZ|=dinFsxk%vPB@TBcWE>#bI-Rv1GpHN|GSu)w2Yb> z*DO6r_%*Efry%H$-DDZ#%`>sTU$ODIiRyy71tkCLi zV5HV$4q}W0Dn`xc+G#iWtj4__y$`p5it-L7H^B&g4UnO6-tu0lnmd z1d_$qzO?iKp|_n5UR3YuC&u+|LKtnTq89iDXt8#m@N4WU!_yhvqsu- z8`-fF(@h?5*d`!?m{wcT1dutw1(5uNkOGss?_Q}n1--jJdW>F$d=l2GgkAY9R?T;d zXy-gnb5mO02T>DSPmY%KYtV|STU|pI5-PMT>f$^8K6#HA%dx30ENAr8_S7OYT2<54 zbJ|>+EChW>H|Qi-n!LS?O7hhil@3g;JguvG`si&Nl!oTf2<1)}_~?R6MU;-4q-LHH z56To~_NNFnGeAZ_Li|G;HiY-6!am3i(J@@iW@Ji3GEnDa_OEsyvWz57K%h$c=c+wE zEXRK1u-wje|Ak{v6wf`eN|}DwMzs$Q{;Hnka}7{Ov-ko3v3-Pp^mpy**h6(~;%u!~ z*?qvMW&oLM1gwK*s}DWc0Z6-f6!yKaqwp+vhipUdhUWG>=5}estc(U-Y5nqVL$IhC zruozAdg?Ft7Ar&b$2{5I(F-*T7IluBPx9(RQ<#(KO6fH;b@h3~VXn20THR9lytJ* z{D3qt&|(P~`-Vqt6>;e;(o?hgbiMiaC_8wpaOQtcSSqLLvaKJt9@l!!r23;_P+RBJ z+;*OXKrjTqC!BTa{NZ@SprWE{hwmp>o)8z1$k;>qHGPtY4aUxhN zrAx`b8;IfY@`fe(^10X#>MR2;L{uBCKWeNj+NBervB{CSHR*e6oZ`*&Ej;;wU2?>b z>j61UdfGc@g4`#00vy=(Yg@jIFps@9Wx~h1&&6*46<@j? ze)TX@N;s|{1u{OXq$%z~RnGo_MvUD_me}PRQodT_PH@X_hTM(4Lmz-e=ol#81|{*U zt`$bKLR;4C{)8}h=|c})9uP@xK3;)0Rr=*EpaGke$Wkk*|A$d*kL_`EBteDI5Es2@ zM7fU|W^);@9rZXHz;e8)qZYf$RW=$}%X8^polu=Ky z`bc&4mg1jh2}seo!e!gp4k@Iiz&N2)W7R;tA&k}jQmP~U!5FppH-~e(HXcph+#M-p! zmg?0+V08A}!s4)7jPqxbA~KV`?YMlig3HQeen+81SWW|tre2vPgD%QFekM^<$V5wO zX6J;m789aN6?rJk)|IbbnKB95suI&+6?>J9<7eb9`30WFE(c>}#%p8_%;g(2KWf~S zkS4u0wXd73bIC>(<tgxIftUYyh&s$=vlB)MCgXSA!(wZceoh~98gp54Owoz7D-mwy#t^IJCSwop1A#t(Q4p&Va;(d_G%nR&hvxoB(YlW` z-g9XQq60X!PN*3=!AKzEgIC<>VHfq(GX8rVXmsD?izTB#eIVbu^I5S$D{f zZn+_Mu6LKsS4&ea68*MQ{T%|y$!49ooh!>fmF3bUAlu?DKUfAwyU!$=YY@@gu}7_? zoJ7}U&Z2c-TsJO_4)n#$Ko)!RjrD$3Pw5vYBR-*qe@ze(4)k9ga^YUr(?rVZ>g3>~ z{~Z4-n_Jf^p4ZBsR|G(=XiJl%jZaW#CxrV;*`s&pnW?3e0XO*s#*AvRH9Z)&N-SD( z!d5O#YR1@AKS|r;ppMSiRt+D`tzOKtPj%RP>rd;veww=D>*m9!saacpLQOQ%001Sq zfWV~$FaEY|7<|`?>hL;i<+NUL$<(;u5X_y{jBg>LVHe0pXDcC-k7NvYU*EqiWg3cx zXK*dgQKWEB%cPt(b(Km^5RQvtlxVg>)kD=o)++kyK_WCM2apDUq}|F zA}s~V&E0pbSuujRL-sz&$qHkB5dG z0-b>r0?Egyj2-G?Z0KmLTfg=&g{cg4!4t{%5?-4Eo*tn_fQ@6s5)CtjvsO8n9C>9L zPu8n9wK2Em^+DwBUZyJ9=$;h5k zsD4-a*Ax4$U$tq5X`!MmaHXf<+fQW;y3o~cvTWEX&0b!#u-`CYU#CXK+%k`%{|Kt;yTRTrdiO=&yNg5|#bRx$rrJZBuh`9=t5HTL{9~Fwoj7%>5tW z+aI#>3=2J8P`alM__)D-@m^(IxMR=Wy6651)O^EqK3a6e{yUddJKwP9i||VFX4xcfgJW`@?C?(dex-&X-p;jaI}p=nU=SY z5vedYzy4(z#4}PV0hf`^VsYHz?2e*kr%aC~Db&+s@l92sf|PZsArTTy-mr!t2iTYU zdOgWY(O7bftl7qH9n-TI6AYZmr^X$lTUv1Mrh^*68yp=(apBk zNy@edexmF-O9}U$B%I@qOOofQhM+Ir8~!pSthai_uby*^-x_9{WUrj}$9eImCScqh z`>qJct&LvXkh}+c_7VSelJ9jn^uH5^GLr?8SkLJ#PGy%77Y-^Ec`oAuG`$CGpM_;2 zny)%#xi$XE#zWIWD> zVi-=-w(bqdjB%(6f{uYyvlMe!hk|N(PM_Pe7tk+ra~`h5NU;)$6JfSR0h{{7+-W&e z_QvHAGjZ0U!EN90j*Tq~`qwO@#WnDH1I;32)p}X_V^+tSldUf-$2~6~Xzths5*K7C z)F^E3pHOrA1a^yNOB2-LHCX;&6hpOfa;jS65STcCWHd;B-Hat-=DIg6k2I6ic;ItZG-f54_AfA7E zhlo9q{6FSt`;DT1fSe9{-o&8YLqD^#!J_DC-Xz-u=;%E8xxO2zx?U8gRgH4rsDB>lNzQocgdlasO4YR&UuSI}2IwE%Fn?~9^X zs&T;0|J52uT}r7BZ<^0gIt4Tv00880%1cQI@B&OCL&u6n0N@DB^@?VPY(+0?YHU7} zn!C>Dd{I}gSX3UPUKBNezT{FTQOn##*+tq$E~?6K3Na9S=Co^15hGZRx)3YZ;vTvm z8*F(Emv=t@W&l)uT#7*j@(I=5@<_~YLmL%0W|6%QLe6L3c2U1}4S&3BS_5xtHTluw z6@FCE`>Gbmdx9zz@IT__g8u8}_rU(d)CuLI=N~`r9f&5goh%NU&n8JUJ^CbCCGYNq z#awNUSvZw2RFjM3AF#Nz4yJqV+MP}DfV>;| zAt(N7x^}Nnc|=2x?VucHuq~LsnD;oX-jA}YyFH^ie$Rj?zlS1 zcAkw5&}lUWiyUpvF*QafXuKW27$lxFR*XyS`8HVNz(h*hChrJ%dX5u#dG3et2PYlR z{KgMG&FNhjy$A_4Hm5KjiFA?x_U}LXbc4Y8hIDg(@p$+49QrV4Kvm_i*3aWFD{%DW z#mQ~rAJt^ODRt-V^$f{IZSunBFaAY+mvZdIviJ7?gz1YFb)vR&nUd0DL?Xq0Btzf| z;`ZLp89DjwQ~2AKLQc|d(@QdcX>G$?av4Hiut^=j8d%fZ5n}cxFSTZ}D;j=u-H~Fp zD~d=<zJwR~SE#6jy`ez5 zB(;#VW&EEAck$fq!TDkfm!lCGOVxV8Q5r?d?MCS`8bwFvrFt5W6+NbK1=wRET?Y(d z-P-3Bwu@d>6nW42ZEMDToz%S_chvjKkZCC{*JUgz|0^^b4mdiXTM+OToSlUd_X*f9 zbB#us9l+S=#XX5;;|+Yx&+;>)yhm+mB8|$BuwOsWmdB?IQ!^<6;%ed~WWnxe2#14n zNv!a^SXPk4UdayHj+==s9;P#XOG-7)uU4?I1)Z)Fb7oP6C;^6(acRiVywc+t2<1;8 zqK5I?1-WNQdZ-G&<6v>+&0BHk7#DdL;e;ylBS`EsFG?gtieg19*7sgTUBhDk)^mF0 zh4i3$aU>f98`W49meCYCiRA{DjLrurFE1->5M*OTLO6|REf?KE8Z$X#eW&H(xBGSP z#N!drs`h3oOp8Oktp?DfW4*?#PLeDgp1}_q1PbV0kyb@$fIfq1y4hFulQlx+B-+3v zUZcleRa;%``t7});?sZj@^#luew9MU)g>q@xj9#+_M9IYw}=9+{dxC}=WQNQ+slaL zE+4Rq?1N4_ z1#49_6s;wPy}wP_H1R*S>E2(vHb(b^dsOXMPLaI-QoQCvb1Uf5z{iLip#yX`QR9ES zR3h!#iuGSbCA!J1Nh_eT*v0R8Z;hg}4dq4v7a{vb(;K_L-_8}k?K+wIro z=YM_Q_uREuynf7Y!{YiYRdJA8Kgf;%D7Q7fvLs&rXh0LISE@@C342L^a1@0DGLwO2 zd4~DGkZHAaph>!6X?&qzGBv);+HJbLg6%`RKw*R`E~qEA8EXla6^;Ix+#h2syyJtv zDr}ddQW;qMb3qq_x3|hQmUCAc@pdYcFR~7F@gLlkMRM@NhQ!hBHOha}y;B62*{*O) z@_ie9QF+Ls$p4Q!Z}&Jo{7wm4JAa1cV<3LuBDB^PK2YQXld>k~y{1c)SV-f&_2MZtn3@$Xlp82Dw+JJ9C6WS@2G;x9V!Q^9*=IwbdvEh!Ca2GbmLU6Z%npLFU2R zGfWiG56p}+1LKa_El)H8TU&07odm^cczD0c3Vho09dzZE8hfTb*$D#@vLbR=Z_Dyp zfA@e>3y?AlIfK;V!Vz!*S16K5Lg?PrE$7Zu$Q3sHTpbdhoWW;V#>r-1w7QmF#vIVnTnY0qWKna z(cXayykw*HF{4UrXw&CK@@EdsE>e{0ksldII+BL6YOq&Lf8MhJx8(^J%G*;Q77HP&Xe}oL<-2 zs}33hPD<$>eo~Bx9aisMx#*Cid~ zTX5I4mwe^;A2g5X;e92C9LV=f;y+A3ld1sn@j$V4TJ*hdy8lw+(VQh zjMN|dXenPK{obXbg>feK41*&j`VgSU9qHjq^jC1n(xelY97~@p{NB52c4tY~|6q_V z69V8RXT#HmZl&OrnxQ8hW40^a1v`p99-;}d|I6oB$5R8}uKg6Zu;H})4}kqKu?o4< zXp||1;=f`_xxnjjFhFMamQ;t#qYT=|s&7oqqyf&~&~V+E(c-yUqSN-)W6n2N@Ao4T z%A)x@56^hDSZyds3+-J%U3@u z&x?!7y%7q!-CMbDsMwzAdnIv&!LlSWH6~&8xrPZcY|Dl(VNH`r?Q@Cq`Dw8DVZU{3 zTr=^{_aEax2B#9CK`BPI1y~7&hzl9w!4_Zc(Z^{JXfTm&|)`I4c@*a@f}qf{Vi- zlcw2{RrHuG`JneRSg-)H;E`CYHt!hzcz~we#{G{Fxv34n0ST=cX6{M@&qZqU zy!$KU`Kn0&2@RuB188KPV1f|f6siym&=eCy@SisJJ>M)Auf`Kn7&$jYkW^jC31x$D zf34jf=a$U*19HtF^v3AF&`UFY)ZD1NZ|>t$hrnBHeHRfcO@JF6Pzb10AQ?GeDEt5M z^o{X-MN8LhY$uIv+h}atcGB2tY}EdDB&6$sbHnZKZE+{#&TduEvzZU1l6wG87|4~jX_ zOfQE5rzXN4gE7r-Q|RUv0V?YEB%p9SD<*gum?S*J1j83Az}O5kvT5%9HE+Jow$q*T zFLkv)JHn=BLsX~e6WghqwaE;H0UmbTQeOVQFKJ%^srw`5?ZoEddjms3tg zT^)2YmWkX&hB-m5OJ(nisUV=nc}|)d{Tf;GrnffW)2R7}qA%c?Ry8E%6m(ehe@acu zft+vbmsoOsie+!%pvPFF{k7cD;6>fX?jc(@{CqzHeAB3+m2OZiJ)9JHEp33C;krBV z1jt*+SibsD^W2T8I~jcOP}|sOI2T-EWOm^FQ`%+>QFl>_LyDL%HOkDm_~rrs7NQf2 zCN?~xG1{}v&r_=;;_}V_D7-3mg`bz=K+=p384us}QA1m`Mq|}CJybw-BkeVVZLv=% z{r{2@tP_X6%`}Tnfj8>M5=oZ6BX8%r*U-~dU`_4e4O63<2Jw&1!19`8o1p@=TP(bb zgW$uKtNR+=>CfUfV$YE>TkdZWOv|Ptlzs)QrjAizmu!?cYA9uwJhhc-uJJG=r>8qS z>@8OPU!>JppoY21@HD0}30Okg(vEep;fk|3S4>RE_;WV9VwJhG=KMkWOX=!>GwiN} zEsF$(3}jnQfz{SvOjz*lAx}=iTl=7n!Zq!EbAGp<09XYk%(7OwIw+B^KDRX2`Ufv! zBuk}$%G({*{M+#a;#6;FNJ=EXulVnF19C~CksuP-w$h-`Zpm{T%*^sU4pxZ#BQWJm z8-U&kqak;9^R+gKDu1+yoqug$vy)fRrc4H-wPWLQxB5%bol-^FqN<}U8p6j%l70G# zJ}CuzL;77Y-|UZ}uhlpfJAPCHU0tO*Zl5BD+r~Wv-@X;~4-1b!cjRf!;bndG@Pb?R zM_Ulx&-d2ucaUC~yzIR~WPz2!^(v!^{bWd>ih@W%=zRqf*=h0ZK^kInQM?$`n&cGi zoW3SMl}kPAY=!Ooz&B%O#hRqYD^yoq!-*;nhfSP_oLGR1^CDDmd}mm&ojNBQ8%xFBL0dVn@cv(CRn$ zt{+&o=U|!hpoYc56Q4V;7nN1GtZSB-QmP z*(@Xmpz5nVyHi04LAG2oe5r+|WImp#y{N`Kj0NpH2XfppqW9h~@7?jYTHEZ9i+b-J zAf0qg!)@0o#x|?`lJad4rvtSSG|B1Ci}_819Nn&To9_>*S^R$s`7%mz3pS68UkDD4 zVOSBq2<#yiJ3;qRi!%d3Xu#4^Tw^5Us4m8t3!mJw>Cou*=u_jc2^va?hJ7BSNwONu zVT>Hi4p5mn-aE|yUKoCC9aGR3)^8c7lUkEdy{{nUO8_>Wj-kw2MG}%hwvU-@DR6$D-Ip5=Wkj6N{##{UR4e5c+8k zlLg#t(p#+oL~IkirABL;&A9E=UE4+NfP>&~+aX+vtpY}U*Pxo_$kh(4_S5*sp;(Tm z5k)vyRAavo+3;04a}9x(I1+bKyLD1KPUXvn zm1Z0R>({|E8z5Q|@T|QuhqyMx_k+oE)IOvCC#@oKkm|H=chC^A@OQiq)UOwIqMVP^ zudWqF`H+yXR{l8-u3`7^srDp11V%jyVWo79e= z>_!;R1z)2dSfw6-!rXqCD%{3OyOTgwVq<*;GembH_{btAVWo1VxeLU5pr|HW=ehKXR z_4OXTgpzC_wryST`Y;b|ft+9KX-l7la zfLd;G8DQ5U6G%63$Phc)G%>j`>Bx1Vh&$bdiV^Nku6d)az*+09yl>rCS#2!HXDlIa3Zpg;ug2agy-Pj!{zhRzpZjruom@xE9H2MEdlk zdG`E7J#`1uRAFG*c}2HoXn82_$DD?MHp$y#m&vKXu-3mOX9r-tS=@kk=Ox&WoUfgU zgLH`$dnX!AL@*rvX)%S3508LM{}mw~3fB&MvHXFwLwSTz!*W(95)&u8yQlF*kmgH5 zH(@6i6FYppNNZTH16A|~b|_{hCteqd;%a-)m=6vb5&c(w?8t`Tm<5#|i@mTgx2Ay} zDIwD=9&;brGhDu2BzrhCAq( zbV=fSN0DiYT$=WRae{p>`KQ~cPtX{3H&2lgmR7p(*FM+6;tFxZFQ@LRzAcml*`D+} z@NJ>5W>LZhuOiJ9?|Z-~UNK=@O%01I6>{KITv*CTlQj6uerPaxUw(M5846uYV@k0D zZdd(uvEqQ1;Djmv(>1`WsAMApk6(*s{UJV z8#Sk;|IIt)xSY2sVw3*>Ij%H7JdS@bv8aXgXT!=gH_4ewuLa*@rmu6ca z%K{9>s7b#m#V@R?wDc(_v&P1~^io-o6mBeRymXvD--2%QXO^8)Pxm}At~wigB-}JN zb~DseD*4Ta+Mz%*XWWC_DUJWIVDC1I#_rQNQum4}n|uvTFuug0@aDdNRL_4u zd#g&_+*YRu8;{WQ0n#D;_)z=JiQ$jVeNKYb2Q+RyAMj*aZNSUX>1%;!+`kS;oZ-Z< zsc~@d_45u;>QSnh+%$03;KmS@!UGaPaM}2gsU~KPdNkhXiIb3MFz`3Q5YOI;Liy=u zk-*>Ny2aeOy3r>36?1dS#g+5Dw}tz&c`!E8%H>bE0^Ge<3Wz}2qop;eWjv;S_>v1j zFBnP^NvQLLEjv3l-S2o5Bmme)j3gqIkPus~oO zG<+`RCy>GQ_8@6$kCgwO!p(J}L33u=b*v${v69feU8HH{ z)pW3pQu>}3B0p1I1~k2o+?9#Ng6xyel6}(S%)hh+hO5_&&$_*nY+SGhy(*rXnz*`a>B3*bf3wPGcc!ILy z;_l}B;?}7j)T%P7OcAJvQGCIT=zTZ5)_IAE!y%tIDsqhJbNt9toIqAO&DRk9aYNC< z#FO1m^x_%6q7J`d95RDxguh++XBONrm>3H;ptcXIG?m|sS$1vO@|RabTikkTY@O2~ zX0Z}HUL|@DSfS}pO9>g$!$X$0qq=Nh0oxRM zSYv;BJU#go8rRjlYr7QN!x`TG%Bg(a;f=K!Q&YUZxTh~jEYX;1Vn z9j|pNKv)o~xr27zp~^=Kil3Z0X5M_ALg#&*Ub$|;vPIPBOFOIOisnxI z?ARJ3C0a<%f2AwebzbYm$vW3_T%UJXXBRg6F48Xkzoj+noY&J9rDn9@a2q0K9=V_? ztTe@1*B;Nsle{7Ih~8{8{IF{&HSR zOWz`1;#rqb8lTrNrUpx>lI3EeW@n1Xk^ANJCRc-LvU@2QU_874jB4}N{7z0-A#$l$ zyc^S7b-r@BC;57hUslFdZJeoDLT$HqyYQ`9*=2bv_AGW1$3xFn_=fP@dZxNpV*uKE z)hR%_sVBWrOT9Q@d+;0k?cs+hL8;v14l-|I=?w$j4guCLEe4V|a6h8Y>QDGt{b|r* z6*JIgpLBZRY789uYoF#fT;XnEvGjOaa|rmF6Tjtbj?J5V zO^pLlt+zDrqM{8_$NPun87?0(XXvw}S+XGZ_1Pw|I|pVTP}yUu=5ZVb3picsC!8Rguh;ymIGmF-V>q5}Zr#IG5iP~itY}HMsNV=PqT&{~-BV(PY z^VOKHF=e^@L5pV-_WC_8$8o0)SsVl4CF@>qn1J3^MhZY*KBFzZ)3@f(rN=S|w8*Y_KtRHRnl&6c+1tc`@XfG({%#8pwh`J&saLodTmfsiZ9JfBAC=)9 z{~~C_pN=T>4gdrE4kz+h=Z7@phO7gLM?zxKKi;P?2z)OS4q(z%GGXoL45@G+Zj%ZE|JIm<~lnH!L5bjrRt_8;A$gUuHqe6 zpjWy^zvJ9*4se{9UqX4+-~z1|6~y9%GQIlfejw?SEQ9puiTlTtfpyfejzm$CVDb2U zqZ+WHsFyK`U2xg7EWRa?Kp}&@)x-fJ%kJyS!lL68$NiP0Ln~X@e%4{FfTJ$?yxS5tvr z33n6YX(Op2{U>;%DB&035!gEUAnx0cO82~wJ04>k0jEhFZ8S5D^0v&uzj7!fZIuIN z-sdONxBkt`{pI+tGiHBZZPS{w@>UX$phEM6C&FqKF*sv}Tv)M6!%xKk3o*NGj@eua z6}wHA>HCo83*^D*L7xc-Fo;MPO%qSqc?DL3-qiWzCBI3u>4XXJa@qOpf_C1$nPIzp z3ys6QZ&Zpgv4y%Mqt5mwlRsx+4Xaz#!z04Kox?%^&I=vpYzzTs!E}7iEvwru&;aXd z!Zf(MUeNiGlTBdo;|&}=`cLhUF>*Z}kma$I4gl=zEE}1Te=_xewwAIh{>tT3AyajL z3c+r8G#6H1)@(Oia97M76cg!|1CKAr^HF1U6P0ywpuO1|68uby$omB2G4OqIg zjeSHkO&;~QCN^k7fbu&!C(v+1K6oCaRXkG%C`>VSzPnloyiM6aPi`UXPo2(Ms~fY~ z({yHX?U5rL)v(8vp*UI}spJ+7pJ}$-=@BuhUHW-a2k>Ba69D8+HR^6F_Nv?j>?-Qs zJe_{J9G59s)<@C1#FD}Eq>0DBUbXJq$x0wmq~;m!A}iztNYBvc(?VV96Pm4bGtkwM z^p@uPfSfZqw@&~zH^8zX*s3F^?snC~9c zj!&%Wy{0iIOUC;GK8^OcJj}hb{nnfw1*uvKh2^Mql_?n44`E8bNqW0Rq^WF;>gVgi zH5o-qN*zCQKd|ZDpUiWO*IzVsIEFB3l5Ho*-1uPz$-QbY4X-o=0N)DJH_J=Gz}IZ* z-;sPO#kVkh5x9u}4r5yDw<~b?0t^0nV&X?K@b1BYb9?)7Bze*K3h(J@WiS!JqGS_} zGZw(;{8?u=Ki1JZpVrg>#|kB0>5iB&7H^YXI7~%9i*cQdbrw0*Fy82xZW{!E7c^Ub zq_9~Z0=P2;usKy%a}NT}WA#9zy70@;QLt9s9Mz_|zo}ARX-*+#sDAuS*Z$s*Z4wne;!5$5O)U$^`E9|0O|71_a7^F0k)g*BMFY^ z-a(;Kmzsi@_np2HImLYnQRCTxQX&5@u|RYn>Ud=!@;w>5p5ymF3P&9zpm2RLqD@i) z3@#pbkR8vLey*^B>qA6uEV)A;&mL*zRIPsYcM0kuM(nxBT?9+xm;>2nQlzwKM( zJMzPNjQMh#SCnpQ?ChNO;6Mc*krp)S)*`E3VQ+vHTmSab(#=32kH<}TwhD$fFNov( z$e&(fvFnZH@QPdSMb7&sIZLi+^V_CPZhN9i8d}hkaHklN1SshF>GN zHzgA3jU_L7GOCrLmE4l)RugVk5)(x~O<(vYh9<3<;ef?c4kImtl9?y55W}=?u6uUu zTKa;py=!exCw{-GZpOs&O9XZZ(7sLcwt=Ft;vfJCo+uN3CWKYo`T3D1apN&c5$KFR zkCp(S%zd}%e!$;HKJ0bnW2DFHWx6#G#=5v4h-4f;aKYBSwpc$oiKyS4Fs}0>ADK|E z%0BPt{I_l9ZI+u%p5w_6%4x}HXqd%eO`@j15ATIfpZ@_FxUICs(8xY~B^~F|C2ljF zvwDuAArc$}HBh0r_m+e?Jq{4XQsIyE8+u=&S!`B#CxK*Xv&JgiJ=0q+v--uk&YKhu zWN2)B!o9=xmm+}i0jc|%!_Nf|&~Ql>tcZV*kr`xi4iMWwrS6H)dGuXee>6Pm{Z7$+ z_Sm#L_uiT0I=tx4?uf_kg@f2KNEjg^i`6KS!mw5Uo1{ytNj8@v&EQ=(ZkkM>;v4tA z^-bDT3XWy(C$1yoNLxH`u>#jxR{!YhS?ycxBbN^jCj3`tP@jvgQ}qS#0Oc4=nAb6KyLDGJL!6WGUkd4H>q)+c!!czJ1Lp zZRpI}e_24N);ZfbxOY`kXGw~{NUoPGHbMbYFeypJPC*z**=QT%CHf+Mc15AnmD___S>!Wn#g2G_nNu4AHVU#`ea>aRP6V+53z~h>W{A;JBrZz!7aR`u(5My7HwAMay2;>MKJPb0g5(HM za&7YTy8?56*H>jhXuN3F(w2V~XELmjt1xU5#X6p^&796A{>qP=TUWCl?d?t)a^JU3 zRdhkASiSR=f0slB#$tIPpQE)59OigsBcb-_q1Ly~Ppnv_Jj8&|O_IT}M1A;l9MTdM z_sTt))YE^Peyp#HCx;W!64ydGk49QwxNe)$Y+^)*A+x7Mix4vm2z_4a9G!!^S7Z98 ziGHi_(Muld_ljDAKyUchcaOT;d?5PBs1hfkxR_ke{eZCNX|;c1%|iSou1F+9=}hQj zAsnYABHBfVRtHy#lxipj5#6T30kI2dW>(kWW{dfe&pn!=`yIOHA^Vos{s0@Y^cyDT zT3%C?1o5$9`qvQryi+1i@23TRGP5&tD@iJ-kwcWue`A~i@7Iz)bWZcMW+j!#g^^+H zSlnUi!%oY4)R;B;Y42SwfPr!|p`{R#T0k;aMgSvcJR6X;71P zYb;c0Z7A{@I(nA}V1{F+Z?@8{*B*OagOqCP*9OKJWUk*>LR%fnVUJ;zk|Y)T`jmHzmlIPB_^OW>cWTZd_?3jZ zlMGzg#!sYDlJ}3~F|CT`R1-$2^XE_EORVfz>qn43!u8zm)kx-`B*`jSTau2BM&=f> z3oChsx37LrhD;%VTC>RQ|A`ONxN0T)XV6#gX-_w#N4&}5tKG4Ic1-`G*7HT>B==` zqLRN1S`wI9Q1>CL{*!eI9Ml+5@ z+u5F8=8^i2(dTLIv{$@stS}fA_zDLWC!=a9_f67VhdCVvFT16a^#y|c_+n$Iu|O(g z1Wg4AVm3G1EbnCJIyb|wfTRsVRo>jAF1(>8`uc1xG%eeDu#ZGA7_AsWVoZ^;d!_43 z9`e?f@p%|>l~H|NhKa39((U0(t3y?GVyPW7Q7_kY zA%`fENK;zOE)#3#(8v+CZ(dzf`rc5JYqkFQ-oZV4N@~NNBedfxG)ypS=oBQQ@{>z8!&7EulFajZ{7KcAaVx}qX;=-1^G^N$EIB`GN zM*HW#4nn<}JO;Pj3h+`OrK*633e`nE)A{BGW|4==Lhd_%Jyb;8%_S7s@ei%OzA99= zu%uatcy{As^Z#9yK|9fOlPJJ5h*J|?SC9vs}tMCQ3{bi^3 z{WH0u6=G5!k$5-b5!D zkRN(>fV~CrYR5@=uNn2eD2Wn6BR%|LpY2MzkORF%*BkzAS*Im{##V~?CE#Nbr%I3bu;U!k2r;=>e3DM70o(Pb^;(nN9O zy3SisD9+LfWwH(RkxCshshzY*cu+lKH?4co&PRttK;)s<6(4**6c=aLcWPi{TLC`N zYO8#lL?0HGuJK7Pid`;Veq4)f-<8`fXC=|j;mLD>0;RujzQUR?bJEu*=#LbZw@ORI zT_WAomw01EkWkatpzh^`Q=jo-Gt7oo^ zjM)hSzwlvj5r6aWFRH5gZg+{{1B!EZZ#O%eUfNbH;v^kjQi5_E6-jP#hZ=O{jJ@7J3TPV$0w<(iWFK$DXG>WxpnqSYSoHw#d+b8yb5%a)8R1~ zDV4Fe9I639pcHPrl#X`sf)jo~>pXwiEA)sDKVkq9%@3a1tFj>W{rdhj9h%^P{v9Ef zIq?H7j~DVp$Zt%};YkI0nkDoe9Znmks+dXzBr_98t2fA+lE5~Jnc@xX$I0UKNnA*V zb84tsYh9e0m}Fm6V`(+-UmMCx#z510g1O8P?SF8Nt4N(K01;64-nXp%H$L4hGiZqT5~rh042M3!Lf4Et=0HP@!`@*}zqS<<6COTW);pZhgf*J+at4Fa#Pf@J?{ib6bWkLncb9-Ij&u{v_e?U_Y z#Wcoc|0R003t{~s>Wf`RR4yjbX2jIH0~HFWu@c1<7Q|7fKjxim-6HW?TEwKNp!zLZEG638n~zU64!U1!lqr`#fxsZ_ zx=!2t;F}F>aDZ@|jZy_Ew6K44C?0GgIsd}U&Y87wn%Q@5T|*Na^trqXgM~7XxTJuR z0~FLm#RSc^HQB9*&`QiDmp(-4I(cjZzXIIyoCxsF9 ziB?s}sY#c!i-*{Hz^TAjSE2dc-Qom3VoNo3EX0Bm!00t$EPDE6>Ro?THs#KDKd3Q% z7tuoyN?dN2_cG6kpH&5_EoQbxaj7}%YB(>eGl|Gj;7gCneTARTj#wB33cdc>!EsOa z!8wN*W%94~)@#w#1T;7EAH;LIm3pGcPC2!{la<|q(-+AAnrL#QtV2)+L`;mBD3s%g%M6Z^Q z{}LhJpTw9{jP3m<8zNULQ-K5eI-QrI(AepFhjS^&%u}j>@1>N=_v|u~CRy(fnIvD{ zru_avoa1@O@P)lqU@Pr~`8rY&&8Zytht|}$XBb*Ct?CbQ=M??n9ospnoNkS!j_Cyg54&SxGcD5kBWUc!e@Q?xmDvT2qRn5#>FD9-YW1}3bGDeo{>R@x3 zk{hz8Y+O!^-h<#E96<@W)BgzRad8~jdArD1T!22@n^L!11f?qR;i3c4Dmx#xB29xmf`tXlX|_twk7wiVa4cd$SCUMXY3^&P#QSXHRF`^7B4pX*OrN}+)T2K#%ag_d zL>?%73S5GAOt98lm6jw;9^BbK=9uy~UE-|Ow<)k{k`!O;j3%ykpr$lxEdqJN?^OH? z20ynbE^kD>aGR0Sz7mDDwq&)=$&Pl9tABWT@rXLn%y;MxFQv0(%k@fVe?tfZXq0g3 za_8iS2f*SxUEdaOWLTYEsm|TzT^BhRY&ND^ne#=BcE$TnP#|1@XVmWf2(R6%c~>fa z2#pIY{!oTlbst#Z&if(CacNDEa(RinP0fP$P07Y+<+shwe!oJDNTGZ%gkYg-)!SUA zDR~V-LK~24oUdAT>W}O|=Voz9X@L2=8jaKH+o}T0VhT&=!yhmPK7qmLQ@k_>IE#ca zTU#ok6$Is(GWAw+8+Qi*Uv}M+2J6V`i!$7n1{!g5x0vc`Ts&PaprObhF9g*bp%Z{l z_I5-Zs2XwVzjdzGyV(0gG#fm^d$%nsO2lq{Y!v$UWSk-cLWU~ODwWGnvlh1Wf95(w zH+#w7-!t#-Z2zo&OTR4n^FtS#YA>to?A;qtPn7}>2gEO)O)+|KY|$oX6m*<4K^1p6 zb^;ZgumGdj=(m{>-6ZgBfbI_H6w=%N4!!BXp5j*+QSyV`LGv##$nm^G`mk0I|DO0 zo|d_ZO>*5RdJJx^sbzjT@NqB>3I*D{1Dc}Y%=K}Ko0>*A2ztKTePH-AAhGII+MK(w zMgIh#0IDv=>q2C`mBi(6!Vyi17KA||dLMRxT-00bd8Gg6ShLFg?gwdj@}E*H23NJ|9^ z$K04x59a`Y#~Qk_Rd$A!sF^KWJgk%Ipl2k=`Bt=>E$o1ir}a| z7!=_71kkD(y9}G zvE3NmoV9C#^-qcpF4!nFUr7ZmLU(|KHIZDBvyV4vN@bEIR_`ERygJX4 znSEiE4pKo8(Fd+*2xwh6^l^4;{@rlG-qJ0*lkSeeBkQ|TFDFST5lU)uf`$11K!(Pd zBoiA}J?tX z#MdTEbSdN`DSTIvR)|yDdW8VW_8<*|>`sR#?xFVk+BCVO3B4AnVA$u!-TZekOp2n% zH=6(Ot1@(ED3zHCT&`Y9|ATx^9D~!_Ip-mU_sfq#LMWGte01??u}#lLpEo$95zfP* z*h)86$2QWX8W*6s5R#ToS6LaX4Jfk`V+%VEWK;Cw+5DkIE$lx-1^}$U{!?55w*I?q zzzoy^+-o}-jTYP~3`|QBXhnX$J$rIv|8uF%Qvbt}uD(8Ne@C)88NlV7s`ae5?E2?`6FvzE%zvtwGny#X>BKB|sD=^Z z-&y-i+0ZEM`8hZQ1beM*4}F=p=jDYBRpQT(?^Ym_DbCIZ9$WdRxLoYhe~eHGI(d3m z?P6*fH)RGRMPiuwq1T=c?;iKH7_W^%^JR|IQUBiJmE%7r5WSmdh zzUfBg-HYMFD92EW{nvw+?Ew&0kcbRQl*<#-O$HfXfjyX!F_srdj>DlkI3qknp~mTL z64SDQ=>Sshr%n71#eI0KbQIGLt`hISlc0#&MH97 z=TlIUd#0wFu5MrxJKx?&$H)J^pi?ljqt%s$#2C9fyB-`9Ea%nuCFTIIocp%15e=AG zn(!YwdJm34a3}|ROujIF={uTkYvasBtC5~(3~}z&>Jf|`vF?c~BClECGYb}5}{$S#*4?((t{kuD_Em!m_bxGT-w|5Hy09a8mRm_}?zk3Y?ma1JDIp(D5(uyJ^ zLEtIaNf%D#H{bm+yqrWdxroSc558rL?&CH$CnQC%&xs#eSkV_o#wk2Ip6TZYmN7FY zwQMxYP8J`f6WR^VES~sa&qk6Y1pt%&gbS_j9&DL-<|6I}IcSy-o%aZ&wGnUesio9+zV(4k z^ZSGWt0l8-JbX^pygRq3XW;H0eI1TIM3H)YHnq@0x^z{!g76K}Wn_acNF;O<0E%`! zToX?61SXbkRQA1_Zlh`b9itO@|S(BeUQCtiHfq?^<;b_(=7d zTKLCBWnI#TZEGuv?|TPmdDAz)y+AwvtzfD%xYRWz7b(ao50YSUT#6*azn(rDA;lG_ z*dfrO({A`Ur40s?`xYA6-#y`0*(y4!w~kXop}T#fYko_v8%|zB-bRR~aXh=*w6dnL zf18K1w#JI!I(0_h&Bu`Pt0v+@)TOieUy`_p0Kw)jfzG;`758zb%dWP+nU5YR=QUXh z!y!`C9s|-@O()|hgD?N&q8ZBY)u@?tR8$p{he3FGU?hM5<7M12#eN!wSZHBJ;wY(F zoEd>QBPmSqWWAQfmil@J+&A6D3}i)QEOl@$qSH!|mKhO>l8Q94rgA!Zr$FMj4;?K_ zt!<#^oqmCP?7kwlnNU6XP zB5x<(u6z8#l9OXS?lM!4PB(?1H028vz1%)-j$LOm^wrKS|CCix8&Xh>&KyH`scEkPSBSWE^$ zC>Z!Q2dC!b?j(PskRY#=k)vZ`Z=2YffvB<-W&TTfu;9SU8eR5SwD`)P7g!U#$4%g5jcQ-{S%17uCbktjhzLKe9kZBjmo+~d`PE)scWP0^(t ze1_-2;C{-TZvbnh^Hh|%zfbGWAhB!c_uI?=J4&A7pa_)YM=yl!dGL{6qMOsEI5aW} zmhM#cm(^=dSECdlB8TOsu7)aib=qe{fvIkJyG98G^_M6RffCaY@jo}gY;?K=$_&gkC{%8X@f#uB*Dh{7eJG* z!=$M%z0HY_=(o$f&bR99y8rpkO;wo1zeRFA3wr+Hb$vvvQ~U_Z-+Fh0{Dh7`_a+3E zz-o%3^0@x(ro$~hOiR)GZkh8gWmxRbH71Upk&R<;-L>h^koxiY=0N@1a+Eq@KZ9D+ z^|8kS+vu4L&1Dx$ls4086_x&)uqaZV^5Az1Mou(nTz%Q(jLzgS;=-PBld&RZ^!D}^ zOKS#3*0t%j*iVrm&?t@cd+eNA#VfU~=yzNa9B5%tA+;suP7l{4$I-q=ml)hkU}`K9 zL`KDd!dkPdf%(dxsvf(fTm~rt1b|@%8Wm&T>R=p>)mOd=aoo<5!}O{5FpdQi>i@Ru zZex#6pv|*S{OXy~8jl`FT|WUL-{@t8Hw4+2{GrhSk!yCJ>I%GEC0Y4Vx75x6buJ1G z4ogfd-=E>+8{K|+T?-gOQ17j?nH}JpV?c1c2=q1iBB_(0vNI2}-wLeAqIjh8_g|bx zbA-u`$Cl$vK*bAB?tOa4@%^{5;n!9O>Ms^W$q zI|3RWLAO9Jz|T$&AEmmN_DpxQ(Pf=qUPHdYf0Sm({4b%&>9wn}dJot`eSlloPSTM< zgf0O=8DWIFf5G+rgqSqZQ8K1l>^dNW6t3~5#Ya}v@=UVt2?kH<_lZ?X&&x5>RPJe^ z5|hMELVha)3D;#vEzzz?5(+}{GVeSi=$}y(psaG<9+`eVr&QaK=b0giHL;Pqcxv>D zpT5-Zdm20dkx15A81F79b9Pg*IVlnm$LAN)h*O`Vyy*K#B`wc3E3uH+S~FZNqkc={ z@9c%0mUVb&VoJftq=JCfu}sKE`>1{`y^$bvD4QoSm9Fjw;Ef`+CO~T-X0=7^K3NnT zv=)gVi0;-{5`nkl15J1_yDsl$|AScp-S;;==+_JpZ-bqR-%9`6ZD++e2^6vcQeHn@ z^}{6OWawGAnu1ECgE~$3nzUy`FxloV?Ugq@o{~>s|K)T9L0TNOn*hn{(9hu~;s%}x z4}1QEf{HDbzM~F}M%}$BS}Atk+(ydba=7M&*A@0VXy)e#O-}p_3}XJ>8VB>GDI`J4 zf|Np_-`x5$_`?|l#m!*o*m%nj7-}s{a#}QZVeWfb^RErZZ&oy524IG#a&R}_y$&%m zHTD<2QMeygm7$ww!a-95%>Q|RN-`Xov(SxR#Hl*Z(`hcgu@}$pmY!E80Hj4tinBGD zqIUrIIR{>knpW#v?439CQz7pD{#jcXB^=U;P5OT^Q5IJaI2jKTF7DH4ri(ZT;Lt+U z%GyZdXO-g{-?kv}RD=BAV^Se*QwX07t)f-TuY?$eU@JUtWJSUL!GXbukF+m9Pwi;$ z84uJwKwp|&>X9TyPB$Ej(^zZuy7`XwNPFdzy+25+PVZLNo$-5sM6mec_m$}N%r&C~ z4}GC=C28V9EBxh#&JG)?Qh+5ew_?u$1s@m;;|a;`aofZMpw!V&NpI(bR?b%a7q`vm zX$RC?G*hs+#{__lmBX|O@*isH_VGVhBxat6+D*X-E{I=h2&4HUHmshWrgPBM5*kEs zM2E56k7uJt72laJCY7%M5-ODcgu?rq0A#BWIWHRqc@v%6Q+^WzKraB)g$Aj!W(eVt z9Y*s~UyHK{QtGF}^1iwttm$H&+A(5b$G4Q?ROtzV-uLBk76)^QjUM4`42re{b8fO@ z;q9FAKL-EITn6@_s}IBs;c@O57ryI(U_oD6jIOp{L20KrP^D_G8IAQL7+7lfAynaP zIz~p0sKZ6ju{Ju)b!9~mO!qVsq}p+_^oj~uEyrA#3Jl7;jSejwO&*zMQHx#VE`_=K)iw>Fyb$;6 zLFY4cJ0|Lde-8;*a}8+O#5MHcixx(QbQ2F={PwO(@&O+X& z;1d<jASx>t1zTN*~@ z_OUs?Pe5ySqlbc+&ARW-`!L*~MH02DO4>#^xMCHO%jXg$^>>Fy;EB>I9VI@#($kL$ zTXQciKd+KzcovnV^X4XqQau4!S>@ry{W+D%efjx>W7=?7T{epFOH9 zEY9M742(fB*ETSaDvtTCm=m-SapIB)@%IsH!uRc^s_?6>{?*Hv^ z{^p~SRMpBTzU@N9APX^R>-b}mTh5r$6=gJdZ_=m=4qo-cw>Ew~ABTYCV%iM2lahjn zX{Fm7dnT%(x*DKCTx}i&T3rhH&8??$Ebewkq=+Z1-ld!ZQsb|%Ux6L=L&whCmMmH< zOcwnXf!c|5fIJ&pcGA@Im1Fj9$ZyIrNP-Fq6n^f8%lCvFkYzG5q&i>zfQ?Jb?scIN zVN;di)L!_+lT;kVL%|3pJpaY`j5i6=N&ry{bDyJx2sKqwVkZEzvUc5N2=un9IK(vd zrZV_n3_#o_N<3$K6&P593y3xa0FP7t6T$}{KRJ=7c-Vt}TUu;}S{$FfMfkAqIY`X; z@Bwf=RiW-55{G_7=W6}a|M2=3nf(?@3B?it6;_omWC4Od_3Xr{BEb5>5EhgnQ=ghH zeJ3_ww_jy&HOP~ziB0A~@|@gA^m|6?1Vli;5_I#7e7aAX6Nm(p!RUwZChUI7`BR3Q zczWiDcY9#X-JSMW8|#Psc#l^i$u0*72uUyTc!1-VBFl`h+bt|a%@b#y?QSI%L)T7_ zvWTCiSl*C|2QIKXUI!sM*)36EU0jLIsm(wbbxwxOb#7<`V2Oo>JAPO!X#wYukIvyQ zY{uXMe+9trAqu)9zGAFKjGr17v(aq}wDL^R5^G5HOmL5A5!v5ds8|EO8++0Gb`lU6 zdA)=qCL^_XC>ts%IH7L%e>8n#c%Dtyb&NJPuGqHKIBC3uID$`4{ZoKCPWLK7O7UjqZ(2V`sq|1+y_LFhkk~$^NIu94#S2cpG{0LpdnZcc!Yc4vhcP>bzm`;+`L*ghpevkqw3< zYoDIDQh1v%{;iI#M9+QdZx@1*V89ab-)`s)pCsJPLxveTAc$+qr{0)Oer>0+Fl|an zsJ3M((T)46oC?y|AF5WPEKC9fHi{Kx32YKp3`afD)!ud{a2lwNO8XskzFIB~nx7VN zO^d+cH{r-ONmAdub~Z^3Ns?>4IDHj?6SKc?ISHofQj|)1$6szwt;}eyCIGIZ%=oxm z6JArsPr$pL3tnm)XgrH4dG7UuqIRZd@WctyBv4#asZo`u<*geInM9;0k?C!>JeU@& z>sAN{s(cr2z$Ud`Lty7dzyBX z=PL9eg5zO?aV9f40o)@x!0*`t&)0RYQw@Z59?yK^mnDQrTr|lG3*B*vxG!hs?dYjS zuLUyjmv7%#c+~+;zMm=76Z77*0vb+u)7<0o4eaKI0S9W)+gG?*=f|c^8rpav62Ay z@%tgK6Xh3__o2&W7Ui)8Gm3msN(6-ksnt7Xks$)kB48%Odaf=%1T43NJfecFgG{-+ z`=Y@fl-`sP)BeXSDi~zOgWX<#0$=V%xf0EhZf*1qU+-W5G!i}H1l+XTZm6gsREe)C z?b8FJOtLj?b5P*<#W6i=_llb1DYO0gKBCZ{#}n#|KO;n!T^%+u+5#OE&=BQgDD=bB zD3mhspM31;qNb@e#)&ab^sL_JGYGGbil^6j_V_V z0|)5RLx!V39tQlVVBz88yRT5-cxod!Q0`BU+UPur%5bO_6-6!p-3oN<+@A0MsMW;7 zTpEk-({rouY+2O`KBn--U~E;#%Zkx?q}Ps}yY`~=wu_YM^XWgh(obmQ!v#L1r!Va6 z<0Lhk&*G>X+VS>1Us?7hOrotx@*lKD8gL19akTR~;XtWb^`KAbJiQ++CA7uJVt@!S zI}WbK-WZt*P(4lzYmF>cq7lViY+<>gN=FD8;r57Jx|M<}_mk!z}VcUC@7KSb(^ zwJ1z(YKx-czBcn;PI0h*M?MFLJ*0ox>O4m)K^- z|0g7Bs3w3PQsQh7JN8M+Ee1{Y&7lbhtPII#56crgVIVpjMT#TA1IDfWe=392*yY>` zI}@a$_YmNC;%Eug)CM`f;(#bP_dcWzMq*-SZW8{cf%?5~Kj&JTBF{t6S9F%VS<}yX zgOD`&o9_1DI{p?xRD4K8B8M=gMovM27^#BzlY7yxJS+;jfc)l?Fg0Fko zr`YL&$Kx3Upb{Pmo)c`Jqf?11m6u*m**cl=7Q*r|dwUDfDp z4i0bD&>63_f2Y(CMz@n2 zHpu1tZA+ou0L*u%HpSSdBKU)AD~QuVes?TBKll$e)C z7Clw)^``>+{99to*H(vni`m)Met;-?*!KN2&qul40{a5QG9h=Rbr3o65buWT&CO6Y@dewmk6 zR%1e#Ak-P5CShK!=5bvIrt-YsjbBmB7NZ8Y@@~kLe)!2>4iC0t*vYoLb+_~y{+5t{ z-~|Vsu*0!9K=Ziu63Wox0VGcJnO}`L{H7Ss85*IqKvRlDplxW$AkLwahktwGv8K79HluPCkr0$}-v4e0_D=a}$6iIZu%p+Yq3GxM#C zxL+VtHzZMpeha$pXiE_L#mWl}3R`sPA&$MoAynHLzVPnbGO*8|WfU1|$&x+0ULJaG z*{{tFjaf?lIpMh&jUe6*ePpG4B!&rsfzSK8(FFszW^m_secB(#X5ruqg7lyO@5wda z`vblAl?j#W#Tm&pPcTDjVQ3G*-~}gZ?2#$CT>#wvfriV`qx1k(t}@Bs9b7>nK%exY zd==)@*qVyv0U|#{bA7^Rn#+HK-M6(pv;wR2e<2LMX@HW=*L5%2*HjT$S1$?wc~}{f zCT~_(ev%fDBCbYz;Q*fUriTr7QT3YvN?)?J_lA}f`KEqcG^CIK0xw?!pgD0&@Y@9f zNepe6R-_L*buF`Wvd6KYT&N#h&A`-|UU^L|eJwCIQL)P&Rshu#VPG^{u5I4C25YB=09rjPGDnCM^OUJk8D#q z6ldbY%eF#_01a67aQ;AM=H^&YD34Gc2%a9~AwQKU%P1<}wOMyDwWhltDpyhK?dX#t zq~Pi70z?p!EYs96arS|}>=tMn%Jmm}#nOu3uRV&DH!UZ=oY)PCahyzs2R z2?Ww*u!hF?4{;y}b#*?vLVoooyxqrReg8O7mXk~Ikd<5*^Mvt%~uV)PzyP09tscTRp>+C&DP4Bx+*E4063 zAU4QRbQIOrCk7niE^7C4{}FY=Z=NotwZsey;x3}W2y-8be~}}u*O>f-LY!*qSsrxclM8gCczEcpBrK%8H zlf!#e1|Bb=N$g?2RGRq!Lkal$-OK~8N;U-kETXv6zKMeQq2RwW;^~B`g3t~*dKGEpGvlt=Hhd`jAVL>w zb6cncc+94&8DT2e;il)*<=HRUu9Bc@z8E{c5GCmfk~if_Nai#xT%ZSv*iJs6zBByL z^oa<7g#XjPJ4xd-Tc9Gko>)A!=I~f|Ijp$u?92py7~nkqIoC<85$?|Pd(RrtySm-@ zx0G8V^_;l9jsRrhw4X>hd_Q56T%-?9`F7^t>Ca|Tz{&>K zJpG_Pe-;0w*=1W#gb5%aK<9Ki%Q!9$5~NJ{QY62sG`FB1xJ?KQ*O~9#DP3w)-dgOx zzl9OD7L4Uxh6gM7p!G%r_D=NvGcrQtiX#uOl5G>}DnM^qzM)b*#IvBl2BL9ewEDbG zsg-eVFR*QxrT<-5J`t}TOggOl67`xw_ObwwhGIEQk{|x?CRhwL&a?g(y;=Lw^_#JB$f;qKg&F&N`_yBYKY!ix&xsxI)E!{2Qr6L6GdUDNV`aM_PI3p)HK&-I5PzeS? zj-)?0yV5ARXG><;mF^Yn*%5M|Dbkw|?V>etN^}*v#d43iF(TWM5qoGL-%(M#%NW&x zc1!q-FL2wuP=?C}(#8Sq$>TO6{uW4@Jgutl>R#(5F%g@^g#8YV_+Pn#0mqs@SUH2J z5v}yU^if0=#JK+|vc4QT#E)C!m<{OZSSc4kioPD=V$%Da1Hj395U$SeYu8`^IfzJm zEUodaTr*ptIvxKott!lVl~sQaggN8 zW)2Da@Z}*bZ~|ju@qtz^oAHm1)47Mv$9WJBM%2(a3Vg&NH2u@-!qTBgV)jG8 zI6G9$Gn4vBk6L*pESKbNGx3`i{TSCy(wI}shSRi(sH(#M{|d7Yhj50RV*Io@^?9{l zyx%EBd=iNBYu1!jN5j4Ao_gfvY1K7576GOG6Fw2Fx7-88TwkQ7X0x6uIN-5;+2j)3 z+&#iqHTH=)#kUSwPEV$zv}Y?XD>Jn9^oROk(bme3q!1n!9fbm1K?-qHhyTO+G>@gT z^o9z$1#5<@YIx&4*!srg{feE)droe;5hcKo#^Cgt85S}0yHBKCfyMPS>?;safEVV= zr+`nT@~ge~(%(tW&o=Vg^SV~Y=YJBtPNSSnQv7$!4#*~9?W4|**t>bwn@Az>p;8Ub z`-k|85!$hK){-`~cp0X9fp{37kbn|eRh>x+$1dYR@8tc%ABrEL0eGc-pbip{VjsJa zHx9aT#M1+UW3m@^IQKHMZop9RcI}a}(l2sU>#C1$Jny~Vi~U63-pOD$-Uk6+Yk79k#Zm6~s?Fmw0y8`!_O=BCdQiWX!4ssH02a)%l z+pbx`eTHQf^`qZu7p2RQ$Gtah33(BuQbqrqi;GqvpXuoq; z?%~3*S`1?o<KKfBjM=)bVj}pC_7gL4F(6`nkY6w~b+9VR1Ft zIk-$yPl(Njct`xlCcD^=hXn7Ny8a|R3MOJJ3lFz>2I;QXyhW3%)Wuvy;tZf zn(b{EJCEHVo7M#TGkh-yK0-|1*r?FlVjbus5P5@kr%D4)mmRR@H8nE~E31!ovpLMc zV?n)szW7}G&6i8GuEtd5dJJz;Rs><25?w$4n^-!Jd&b6lp3Y@oD!%FoRlW6j{lx~i z!5~hPmu0A&Aa9U;5HFbs5@jB5Z=8OKIL%#A0Uj2>3 zG6!&jDbdcrKk){zZ}(DI2zMB3>BspF9+4*tSj}FJv0hA+(yZw$U%w@#M#*0wj?!t# z3RDf(mxc?Uk1b)iujW^-M?y1dt3ty{KT^IIe}$)n7LRuuI4Y{Rarb`s3^d1-_3B~&GB-0BPBq$Y zChbT6oqX1Ou)yS>lSU?Y&x5mpGBko2tlr`4v;8?Q7jwjL%0KTel2+R^w-?zcw7sVy zXy8~s?i0d*hX5D78^Yy6YA0gHYTfMV9tBLtcHN_5u6T%kpzyw`W@hUR_FNxt;@UiZYxH|7jcH}jB#5WvfNj)s$1GdVl6o2 zh#~n#6^DTQ$`Ew8bCVJGn~5*!8JyL$kK{{>n&xQzMU6YQ{;f})^sRPq49+|G=UZU9 zVem0Uz?sHZiDoblyS{{`wLMM*x4n#*;GA^ZBAZw-Kc=~x0DXA!r0%ash9C=W?T{9s2S#PE1w8vi}zrTUIW#oF6^`jExEVFgI zxc?nGjJ0>p>)-oE$9?~6X;frK%J|;1SF}8{re<01SM#VYik_Xf)tAd$fA8{A^8Y@G zgf&bWp3%5y=hhAW$hW#F7Pol6-UcKcI+#*eD zL4fT|9D(*t#uk+#B<{EZft3(a<}spI7^Bs?55kjw`dBE@WM9F!38?r=;oSRB^>-=eSEPhp^p#e{`^CuKf zn?kjE>RI6kpJ+SFc8(+`ig2m8U5yR!{|!Z%V@Mn zEv-oC(S%_0aFrx#_!EC!|JzCW-gZAG=LndjA`Exb$l+MkY0MN!w?vdAQD=X&*9%>y z#}jY)K8j}Z((LO1K2DSfqn4`PjTL${$+|ti(UVZTv`^j=9uO1#ctT56Bf_ve`~#wB zCj0%Vq_sen<2y4t%}#ri?X8H>M=1#fJMc*MNCees8|}VS#GTv&Kg1Ni|A~#pQQ7$zYUqslSi1e(g8h)k7yVEA6bJ zweN5vV1o+9k-F5ZTyA}*^1)z)UWWb)8&4_8I(%{r(%q?c?q|&lkYR+7SV8_V$m@K< zMHw+Mu?c5B$lGsUY#pcvXDpC_t*1MJ)&A*{Q1(mLc39V!l$&;JrtAF`qN}Mq{0A^6 zsYA5rXeB~;TQ#!cjp$|@ufQ$lxn5=CH~JpYbVHC($M;%}J}{)(^c_M0IUFP2c&h(q zki3Pvb%Of_yD9hAoTk)V+*ZLn{H$Q!koDw;8t*5d7R1UH!7%^o=O)bh@wP|3E@G_^ zJY~PVi)G#U3|`s!$RfNsq90yynv$C)(DCV2dyI;RAaAxL5j^U)>m1cRx|m&(9(V{! z;%0;14+J9zto?nDxYtYY`_Qo&J~qy>Q4Hi*?8EvX27xz>e+XT2G8H(I=crK5a-=~!R1q;A9|_f9e^>oMD# z0scG%DH&NipFm3I=wj91Z+Pkw^ z(9MPuu-d+ozYtwK_)Bf&>xL`O%f(NYE!+r(8u)|#XCTuz#^@13lS00byr;j%d*^(n zw9}o0Mde}sZpT>+*+=8VF&Jcj0~wXI+Oxd&qaEv>m2Rh+3lyN)+$PgW^qrOaPg{rs z&Xd?_3^TFe>mpKR#~V#$`x{O8H?4?!)ykh$onDoL;N^VIzddfdZLh}^$tZX?PZ5K= z_27noH3ao9IXK>?|FY?Fk<%pz|0baA{)(RI{)TpQBhb}aXkF8z!<0Ci^r{$=a_GL~rNrz?XoR zL0z4yPGC~^!B4MUT{E@4s{L`j8W)2aOSJgc4yVShcGV0qH4PsnsCmER6BJL`z3NWW zg>P%y^{X7u{i;!%`q#7oB$i(V{-B`jF~REzo0EP1H77p>D$LZQV)}WfdAIrK`c$1m z>`66?+3hHyLE|~49EDiO0y0`sSW}-p(wo8Vc4+pK;SiuTD4&%mkP*W;XnQ>m{wU4Bwyd5&%$2xQdW`E;XHO=K^=I8eUmwv1_3ENQ&>ioq-%sU%F3LWi==lm9Eu*{T{O5Y9sV#$#iNR7(e;!ViGb0 zPuna&9mRuzUlHJD(8o5Zz4dJEHCFO`jt0XspR+lTyk>1piOZMF#9;q8!wR0syX3oZ zafON*t*2K#v^fP*Egx6)fi*GZlt_0y=Cyvmgp^%x6j%2;;O*nK*y{latC`NZDq-NB z4LnG@(zT1ks7t6Se+TJ(l zc;zHy=(4<6KYm#;?;SL7cTJu2JG9z9a-pUEovk0EysfHRHF7LRgo)QXV71txQ zVodn2Qhgi2n(QqBb6&eMxffOJf}lmp zS+Y~MHRlPOI|h*R?Xhca72H7a`G9rj0+^aH&-*Z*^93io?VQwTtGzRz-ETf%V&URS!H`t8*=dBut%^BFx*@8pZC)a# zERyiryou?JNrsldk3ibzEX*C3|Swl>f~^I+Q&?_U5+561&oTyeB*x_KdORi zKilB&uUUx{#UDZ?DC-&~{j-D^Tz&ERThBS~X0W-Ga0st+gf&L`$tGk7dnml_G?+gf zNz_C(eK~g;wB4>i+dk%T#IX*x+B~aoUaRJykOERkd7Ym%z)9$i1V{a-9*=KDZ4V>R zKj(RyR&__eM|%8oyv1QPIdVd;&{WHvtw7z98bb2G=SH%D@-?w7kyIRYP>Sk0Wv(zm zALO|gvPo|Ax+IAfvW;gR{)IkEk_qDb(<8yUioR*;Y__+k5+iE-u64aWWs1aOYX&@9 z2Q!8%c^NZ{C9~UAJXAcC@QV753#QReX*+Hp8z?-nT+R7UBJ93(MY3RWgr2LNuy>8` zI{>Fu`E3IsU}(TK<_^)P)A29oW>p@yqP_cP6p^#AIk-*@;c0X*buVE6@C5A2rM4Av zdvFrbTu2LKz9fU;D%BHJ&2uy=HQe35AXP^!$#Z&XhMn7ZuEk{wX1qX;mo1hCtwJ5AzkR^UDa#(V?OeHkG5a?%n6Z-(lb58IwMu z`)@L;?&W8sRtx{Rvhw}gNWESSUa^WxX7_2kvNjodJ4ZALl^>g$zA8Z)fS9ipk| zCSb4hPg5JRBT#iCk7KZ&Tp$x3N1_6wfH)bh<{X@R4|-2XA!HHwUz7BwycdsP{*>sl zbM=Cy6ik}I$hJg-@jOwP>Br)O-+fR<2Je}ZWn4GQX!X%Z6wM0xL)Yb@L8HsRe{!xb zW8b%_nW760+ZVW+2a!b2!=61Jw?7?G6VtG9BZ+FyZ&vN#frcMaGWWakYUSypd^U9* z%g1k+Gcy~iP8CgqP@!b8rD)Mtagam-SfxiOyFN3)_;+=R zDLkx@Q}VzSp*dj$q3G_=jN7{T4s75K>&|b`}X$}3Uck?x_er840AXdxzB5G z9W=Y>VO}7@KjvtUUZExu+t4%oqvYUrYAmu#@B^*;H%0+Dtn)tJ+mIXXv48TS=)^!D z#2^s>vLfz;vymrMpkd{1gSEabOQdCXxqyclJa!8h zTC4KV9ldT+!O`Uw{ST-ujcUpU%-ldRJh(0}Y754D%(46uj#VwLaY{aH+7J|=7d83g z<;pawcr7IwT;{wFq;j-hQ; zos}HzZ@5m|9Ko)A1_{zkcEpoVsHwlRu9a#?DOL>8sQ;}<}6AOk~KIl zq98$U@=^32YBqV_WuoEG-2lpkwX*Xc>fpRHT)C3Xj>d1On)I!^avp#}fqe zoNhy~=~I~K5s9WAqk1&|4I6D0W1tyNCanliXo1N(0+S_5Y59fJyvtO-yG>}lmwgKH0vh_|;7zRUGZ(UJYU5}U_xSob;$YWvr zP?)wRTD>G}Xv7D)C&^Z&UN<=zFKPxSftbWWr8shhhhwB6m!Pa-l*5H`> zp+%GwnmiCaI=4wntq)Z@2Iu^|6G9eMVeAt#o=nW(kjPtu$O~@WWs7&JO64dkbNmQ{ zgV0&7s`)b-5cLLS($g=zN4X$!h*;ZzYu+!Vo7aP^^C!;dwEt)AC&re5V>W0Els zM}y-Qc~Yf(JP@gp*3`ly{QIAEGPfF727e$quy%5HEv{iEV`;Otj$2Qwk=-X{IAti{ zB|uB8e#Z!1J+E3h!@;yjksWZDrmkLfFh{MW%Cpvg z2^b-nk+HU#MKUB$!pT%PZ#(3xfUO9f=%g(y?3}G? zlV%yr+L~jri9^yGWs=z6A6Q5bwzxz&1E2KKo0l`EYE~-#kB6L$E5EgC^XSV981wgFS6(Ks1#z@gQUV3k)ZA?nBQwGq z=9H&ZkF0_M?JJ+zuiyUEfI9)L#i64Cs|hlLKUvn?niMlQ|I;Faw%Z;*Ac}PH)#9&C zIU5n(H*)*2;{|Cp*NHVM^=^lbJmCk|rx3w%gMzpxQgm>1%VDja zZm-%W<06ncHJn&jb1q)7U`hI)ei7<*ImLA39y<@9Qj8^r?E+Zv=10LstFZ-v{Vh-_ zu#f<*ROai_BX+VG6J1TmXKkD!vgX6cOa5x%H9IzQMw$PMnP%S=$NJ7ape}S6QdRx@ z`mUA8?rw>W+k_II+*9&S2-fv8z(nYQVc{9(esK%QqJRaV4C30~yh;<0uI*f8 z+D=c;;V1p%<$qo^;=Evg@P50tb#gj3qB|y?;yin{7UUWPU*CMK4CWUz#$RPN@>+Wl z$uc$%3GVB*4G(1(5ifj~L5rmUau(TOjBttpmVj9Ke#|5E->5jV;Tj(+uI|JoeAu;e zLrvv6QJLfrWAi>_?-xS3^k(7qpSSANVPR&ejT=U{+#wvGAk7zx0t6fGZBZWbDy}9y zo0Qx;Nr8f&ax4R-ZHLYtw}D34b|0)w=PQdGzpFn`YSU86rBlwb8)EjnSqbq?)1?zn z=ZSu&5k)|Pa(e0aQluo6#R|XS0-OG`P1|I6I%S_atYdV}5+1A2M$xMM%YcZ?ZdJ0X zxKHoQNxw^H8qXH8jRh|PU!OzBuW>||yH%qPeka_>^Ea4^#LB<5lmWD5KGDiFo7ZDf zf8jn-QT=PtmX3~MaK)f;v-$*M`;dA-pre=}4xRb$(778ue4iRJ8+m{eR}mu7t^*h5uD)6=GCGwH{RMQ}+lzP+jf z)&*|ehz7b=R$uaXAiDHOA;-N3)!ua8xU{HaX%t|BhY}Ec-UHq}uRhr$yZI3#*a1LO zTA<(PXE;O2089!1P)NIMV;ph$gGfj;$ae?q-d~*`)<0vrUYD5n<9ik*Rn4|FBKfma z)&B)fhho~9NDqaM_=CTp2#q%Be9L3WUBWwtSra`q1i7>YVr#!ebQ5o%OT^#FW;8?t z8fTHRgF|{ZI10cHhsOov{}GN-Zyz!X_X8zs;BQ^L(|B`qidsslNQ(h)p?$^GTcXs4 zeGgy}Ov%ERuPn-1Q9D+y8dF^2iKYJ>Mn*fKYYVHWI|t?o(GZG@`z?=ScW+_hre_qp zDrnNk>d>8~Jln4uXA)>UMw63fiLNPo;Ro3K6afSI^FT03 zwdh{=IO?6bkCWo_lKhulT5$Z9`n>Uw%Fp=L6$r(Fda^is?gMF3i5=*KZ8_^WES=0< zIAy`ltg4DWqK0k`V&aBo_y}NZ2P}gTS5A7>a_!m}af;*$e^A${qnLqVaz{{VDHr1U z+~B|joW{i9jfxhXU+(h}*av(Wi!%i+g>5YKZ0eR-SZyYMY#GX^~51eUh?8 z*?!O#Gd(1z0>MsZ5N?zbo{S!7IWq;E15GkpMcOm@V1Zp7e$S3lZq4SdtM4yyJF ztEso$TvR+>;;(ICBx{E@aZElPt#70WM`c?O;Ri%C zVmE)9+EwF+8Yshagd=Kte`~L=MVor6SeOJTC=0BBF98k6=cx7S>V<#U_B>F1Nd>&y zx?62MeKokSt6b2oaScZ?mPmIvv;Vn$&Eugx=&}tFCELtgnX7gORs6-f?4iRxyf=6| zm7AOz79q8R08Ml8%W@EYuXw?gj#K!?>S2opc7VAbbL;`j-|tp6w0UR{!9~b-!NL*v zCjNn16W)_L_v9YY6>FyS;-)@Iv9Uc|p=sg)d6VS?9_OPBnW zR6V&Lzq^~s~|BilhScacS^<3Dv>|;1YQ;oe#CM0Xe-Vm~qM$O0k9Dui7u>;8E6%_%=og(}E;0lcpG# zM^xsT9d$A&rY}UsDP*Jc{=#B1vaA)K9ELp98s=S18_i$NHu!r0?-zI^c+Y zk7B#spBOkv#XEW)8A3Q4_Ms6#rD(iyY<-Uy)C^B(;S9DD!)-&n4U2lVskRrLhds$De1-#f0MWtOze?7klbn8z_EOIv_7K(zsKMEUGzS2B;tj_ zuXN&tCWNL(tRcW}Xn|d&f<)Z#Q$jZhE41-F_+Q0CEivHNv5!|1%IYItC;@~k4K+UN zL?SXxELmOEliRpvxUtip^GmJfEZBY`H+%KwK~BFce7)bvyRBWK=n(*HSNhPjF;+=f zx>%WY=$q>{ehUF=T!V=OpZ=8)U_4`&7I`d&emaEh`cs;aR;5@x406t+4F0GX8)#Ik!f@8Apr9KGSPoFx#8 z&<0h6-MD{^^+fktD+BMEOI$g|juiYMx<2IO@)MGD+^@Fb*wjuftEEL#796q75{^TL zJYWesXaJN04ZdoUV^wAVV1Db4S5(`$tqd%6#p-H2UO~Rjk*xQlcy5!C##0@BS%Dxy z5(0fqFsdl)n-AH?0+Gc{fwwo2B|hH9``sD&Iy{T3>Wd#4^-P9IEqwoW6}j{PB=Y*! zDVqv_^MTdr7-+c%xHj*H`}>=%XR1R)QQqCUq2W=@Ithazx(%U8z$}nlDx3}S&9M~7 z(;L!xdqmf4uL&5n6d-L!Zptks``DGx^SY1Ha3^}IP~6%sj}ZR`q&~Zsq*G6XZby71 z5pHamyHOqT{wisiEFbj2hW{AS*YfC+zee~Pq+D#ou1No9z z3IIk3z#h2?=u93~CoFII6%j*kA8VQz*v1PyK6olHxbT2$dzak|>ZU#vZw? z1PXTzdx}NU_`y9|zUs0V0$j*;`iIr!TV;9?2N!XT?2cQIFCy~pgx&K#f4g=BviRjCzzn;s4h02L!0}3tB)F_r%rS>?pU;EY}}WcWh-I z7!_k}DBs?Mqm53&O&gpiBfV*iUZo=I%hj7?RSj!@*poI+6gC9X-4EV0Z2^06-3%q+ zADpq)4BOyl71aE!X$159PDVE`rMRVd$N1_VbDcV*tdL`dM&tft=X>Ss?GrpJrHo{EUj9gN$}7a`Q$CK znY9h0x?=5w##_AbM}drmRm2V7fdQmW6z1)beCo~hA%j7X_{>nUpF8qU0~7qdI^Y^m z@Lei7W~X$e?QMQAoxffjWTa}6a3}EW3WJbevIh(Tpe+pGN+im&Nd0?tA?0dWdX`BA zq=Z>gVKls8MNUk|5djtG;{yT~EA?^`;mse58c_pmDf*EizT^{dy&&XRe;zG@*jJ^G zYJ`ux0nr1f?6D(JKXm3caXQaH2Zp<yGg7)Nk5%L{!RjVKXn@^ zA_x_*_OXJ*#9T;0wG(kT*naE}xk_>j8Bjp&?cav?V444LiZiue1gu!S>;czlEt6i`{RY3mm z-XRM)wc=RIF5%lbM40qbPf&qJ*)h;Xwo7X9&;@wn9u+g$st(t6UIl z)2B@%x+1>Oo1YFjsD-(G*}1|>EP0bqGq!`u8kXiS=|*)iJ^b^3Q(khJ>w*$aL8nU9 zCX+6J7Df%J9bh9T@1LO{ha+I>bjqZf)FunHj}VnqqV0)pv>sr?3tDXwoV3B1A*Nt- z+ZnsP*~8In-YVmgz@e}j0zt44 z8c&*5(Y8a4wY_^~+?p`Jqa3a|wd}J&bDCI5gUSOWs*zkgUw52e+!YMxwpiv33_ilC zwgrmx`GEKq2arRlN5UzR?*bL85$&#s5ayG7xglv_V9UxJT>d?0*#VX`g%r7o=5HM5 zTCsUsM~>*6R*h1#K43bj^X(M~zr++|%ahJKGBJ3nzHc8yPo+*yI*|S)?Cij)RA4RX z)*}E=@c$^M5tzOJpZa<9pjL5-d&X9=KQ$UiWmM7w;u47E&4ST_Ug0JaT7^p>5$!rc zhQWr4rBiEMq|XDhN93z59MR4}P?FrzQ(0#RqoW(WtX+Bo3b>WVOLjH`|F~yzk0^_I zT0yZqo;9eS?aThTFcT6T9*4*rED@7F8#06Y)MpagETeq|zN2irV2^5a@8xE%^TS(O z)|6>fSOtxXB|7Z@COYDpY|lVB)&#!(Dme;AYjY)YMfd;X>AT~peELmndy9i(9J0wQqwEUVgkvW=dsj9YmH1uWpYP-MPk+?ieeV0ZUgPG1uLq$cC4Y-4L5_%`q1k{S!)WEsyB?@dP0S3s3{vLo9p@p(cgF z9!k{5KvNIo_$6IfAJ#w0j;h5;Nj6Teu_lwJq+U9UvLxrCUluomY?xAp)#y6?pVW!8tm?2hk$3={e05+QbF&M(A4 zbZM`t*PnOWlB;@eQ8xE*#-3mVC}U(6|0NlnK22-Hw|%^j+HBXvsv|AK^5p46oEr~j z_H6hBo|8Ekwt8D2p@`HoKp{9EurCH1s#47K6FpM?rN~k5)Ob!m_ z5rM(ll%9r@xUxR{s;;i@fPH+0_jP)(zOMh)_(IuC47d z8;oCPGIKuwE}4T|8hX`)7 z&7&OCsfLf;eB{#$m18@%B>M!6BD&J^C^^Js9bP(B^sZ}o<)d+CLwUqNJ{i)oaTi+# zNF<~{zfbC<6YySjf%5Oo2G5qhY!%)R2_7ip84(5x^-NxSG?q^De!+;Wl28galSfWb z>L*Yv1+rNs*5ujUjm2F|HNwOzL|z^cnhFM#-8RxYhX@E+daqt9x?OkGV{BuGtbnG- z#BaaE7^s;||@ zM>Ex8n^NTma^p=iJCw7%;AROsgvE&-E2m{kG^gO@Z>yE5TTStRO+R^NGaJ=}f#oeeV9I6@5> znkMG(SFo^sn&ytzGklS4y&TS zY%%aQ6T|K=ApS{`2d^%WSYrIx_O~^56n+bBo$2;;e_fSjC;~i+tdE`x%9kiY{f)L1 zh%t>~2T^kt;}|1E>rP?1$CvhY6jdrdg<52l@xS<$qqK?3dj=6)b4CEWE@~nW!9i|9 zwZU}YEpGqEJ@7%+|25!B0jfcqw45CS)sD}eq{oaKvF5~DfH=Gm7r%*^M}QcVy9gvP zb1zG>S{AL`j1jGhR~^9cLiZazvJyWE4KD(6?=WE9k#lU5cwMTvT=^l;nl~+@uW9Oi ze8b}3}Cf+QtsHxq&J-N zZt=D<9RcWlLb~(jl-mLZdbI1G!hrd?*WMCIEM-h}qse66`3z$0OA(tE5w3&akvudy zaOc>~qIjASNQ!`9$?qX)Xnwdve?#1j?Z-561`Kpy6D+0Dtld0@xAn?kweDAqp#Gx% zfOdIGzg8>cxGPo!w#a9HpO#TdC7`5d(v+3p^MknQa^cZlO=I4tjz#BQcb`@L)<>+# zZ2X>w6@dq9E$!ii{e2C5@rS}YPrN;$+f!3Ih}IU5_WaqhnmQX2j!p-`GtVmXQU+Cw zs3&2Vtx7C-&fmenDoBbXf?-DaxfwWGM(c;|jdMw_*QGyyA9{@rYzhq%`?ACP-sial z{K*4lFUa`yt{jdpf2!7Ei*5=T4hs}Som%7wRwNigzwf(2Wji;*er3KgnjMA2)2 z^5<{K)tdxjqlm53ETW1~`nSAZ$RO6NgaQvhvt3@^d!K5h+PLc4{F!g;6{axXid(95 z1A_(A`8MwD0m$1|hqr(GKkDc|I*49bG-=bK{Sjm8&A^B}ZudBJU`uFN5ia!ma~ipw zNGddA8&;I=&%1!1?vb*Se-_WYfV-|Vjs<`NAhmOj95QENl?nf=w~6SdNb)w=Xv)iggRk?5~PTNKWp<&*^3|)0B?eXp8>$Q~0Ji=@!L9mN*n~72Qeh&+- zqkcUzLA4BiV6eGYi zH|>S!_AUJ4u(KemuWAb%C{G?Zkbzbj30@}AmFxWnY}!>=0@K#?@N6$Q;m&BHfakzT({RD=Vz-0)XUEc@*f$^}@#@hn@ z^Hh-EJ6}hOao=%{(%$Nb6aA~Uu>I0)(f%V3ViI2`)I!SEAsXkNr-s9Kj(xull-Z?@ zmXXf-#F{Vf#bW$9s*qY52;>R0n;Bv^xx^QXNzgs0)%`zmuKJAJ-u#&XX$P&ll$V-% z%7A)tY@98o*G~<&WIp@XPRO!=WklCDIA-Mu3>n{Dfhk{s;tD2h#UI$m;%UCJQXsom z17dy9RewtE?!Rm{VvrxmV8jtrMj&<}T4VHX6^!X=1%>idJ;9E83;~6RrG6IiFOtzS zg+|~Nq^=4Ps#=$q&U?cV!rB9WheH;vhl58dtR_q*SnkP?7h)rmKIG3A1R)<2yRr** z7BS6c@hCXGP@iVDxbuv&kGa>JB0ic?mOBoQU}(}_h596vyRIn8?fVN`*S&J9f%){h zjlRLtOy$EItNKqY#AWU#>y4YIKj6m4cRn||t1JE9NEtb5?&?c2AdYG)O@;U!yj-H1 zp-H{j&M|P!)XY-huv@;=*i)D88|-jusimmS#u?aNBm|%Hkiy?tdiC#63WemOe|yhKUhuTzLiThib3I=Uvr@eI>l_EWrjhxeizOJ2-1^ zotB}bcv&5nNFW1oH!W!)zgcdImaiG#%@IbaL_z|z0>oTfbUeyqFV3zAVskrwUQzOn zDpz%ctpX1maS}Sp${N}_wgJ+S7G{)By7l$H;EDqb6^IJiyPO@>N}tP2)z-R=!qt$J zP#%fcBFFkrzX~+E*}QViS+tw+spp1HP9y}9d5xuAz-6CihDHa4-tK#W#AD5mriQ|5 zN%~vIyye+<`oJ$nF8EUN!vYSidBGnXj$b^w@97|rZ&pAiIgbaQ3`kQ&y7PgT@?klD zI-h?r6wI2i&681E6A5GQ%W4kqGDWnZlb8xTjUp*XQH(&cb!E*T3 zKOtJ_XYI2siLosOgwZ&*X>LLx-1Tc!5svC>>NiBQe1D#OZT-qZEy}@RG)M#SgB-l# z=)9Baj@~A}S`rlo&CnyoJIXM;_Prc24%p#`>Rcmj0Y(V_F?Gl+eggTOD8lJs3xQZa zkRIZ&fMt@N^sma5?s9Bq$NXygMm1*(U&}QTDM{<{A zS_u;m;9)$fOBR+cM?VtVl99B_%boazUbEfp{t!Rxe+$dGZ%a|xmbTz88f@P9kB6ms zCH3xV=hG4$3Wy(Dy=zy%j}?4rnJl<7p%JwdnI?37F1T0jwD~9Xkg2#I7e5R(5_f9) zc}Pbo;h3U&=r7Zge}v@1$vC#Ft-^_G0?x$Qfvb{k)FUHZ0Y0R&vp}n>_)0_M+%G9T~4kmFs==MymIQU;%2R z6j;Uml5>j1-j>KD{Fr3{t8DM7J+o3XiE9z}Wo|=ey5nV<`6;{ruIb~umYqP@o0@km zhd=_galNIWM*)I;yAE%T2yW}2e8}2mf#wlQW8QaI$XBPHA-J+$Y&Bel=YTMG96tSH zd=7QLgLQkkhm@jaf)+bZhU-bC@?%Tl()jRCS%35}4>6W;vyeKhw_0U)^}Qn^t9{%il%l*~cyJu7-x1nKcg;#M*BbJF-I| z`3{nFN_^S)theK%L({rd$ zW@D4w><5%6A2syiXD>bky9pYZz{oNZ)}nS6K9Z;__NGeU(e5D-&yQ9cWT8Dzd|d3$ z@T_hW6ruTRea3kOYoi&A2(u~ZhjJDdD#f5Z8BO9CfVUc-C`53L5PUU&S1wia%c?(s zUP@XRBi7#b=p;rQB#n9yMf;$XdZZ^NZ`Jx31D|zfNHOS`gyx8K`N&CCRxVLN{4U=3 z)K=sgquRMU3{KoA>yO%o`P)D~y=2&9O(MHRO5s^8Ar^ek=o{iBK>#?O7Lj>-nj%!j z%dg7l0URyX^oLUevG(Fjn~0=)H0(i}>TG4HDb)Qf-!0f-=fPpWGaU27`)x*}LT_$H zugF$>9d5w@*jwUwsPe|f5UtPcP=!;@F4fnMz$ef_lT8)%RXonjqF(QY52T@(QVU=W^z0i*Hm8E;Sq;ZC`A{V0FVr+xSD!dAHQywreUi zX3ysLR;d@eMIIF(PS65{h!dPx*7<{)52yHK8t^~=Zp`lp9PKEvja3^!{A|PRsTmFx zI9P0Cc_(*t7+;R1?rrq!@IR!G_|h>AgPE-~lMDj1`*qI*We@oU9aihFIuf?z15bMc zc!np&iI9;qjc7V5;{D>=FFWHsGH^P#IGkD9-%v@)=WfGeo)NdBFao(?D^hh&Lg)43 zgWJNpYVq12D|ISA?6HckuWmz2Utf)l;EA4}-!og?(R+FxHTmo&4YukdLC;`~Jgc1W z<59tQ>8uWLmz*!HMio;(#=oDwg=^hupl#O*P{X$T?=B2^4w3TYWS?>cX047LiKC6^ zqS1k`hpM_}cO^TXNtR3xSM8R^H>1(kF^LOw!dI>gu5ITCmEa^(6UO3R8D2$qbrm9i zP6hmDP4mpz+3|&!UnN7-5U-jJ=8susbLCKDf9v?Lf-p~$Cpp{r_0lZQVkg(#@Dh8? zMaFmUBS-Rj5y(WswekJ=$bHClxqqrJh9AZ&kdq2#x;X$-VzCb~iL&?ag}jYaL#+8Z zj1u@Uf1N28V>Crq>qUl~;rZ2t^gd*SM}JBeNjwne}vGS5*p#~VrNIL(Py=& z6M=YDhrf^s3>@~C_angu$7urSD@Ldip$N@G5Wa^>8`0z@Eiu~%M;Ykt%$vm z;lUX4JD6qBhd~wEuShaBz>%DrZsBpOCh7>}<$hBFzMY+`xUSKz zU^jV*=S+kJ#-u}5f2J7E4J#Yu&|ocOn5vA8QSY^qGw?n-ZYRfgt%)rZzo4E`D+dqe zv|8jCMCJ^A$E*GMo26@sx;l8K!)ER<#nUAdfE4~r>lt)lH^G!?;bd-5tU;d3bp{q^ zh}3R^IO6&AcDX`mZ`e(3>K2!$AJktF$-n-dA3>|W_S0s6m$N8^Z~4u(b4FkeECUn6qd+-r?wZUEfjk%MR9^OIG}T_qQjCki*~Y}#9o|s*=^!?u1}rKs5>eH@^cSwDp&rNWNe*TP ztue=l!Jf#69?y|{Z2iW;q>&*3eg-$u7v7F?^Vhd9RG@)0%JI_EK{doN=5|k${TCX)%C98%oc2zy9~#o9I(}F5BmoDQa7g@!)BC*Y_Y_upI$j9#j330$%4}W`0YNC{fO@-Xi zmX>BlKGwqX(?A^>N!|`oj-l6CV+Q$Wjrq5rg2*k7&|r$(g2ore$8To8y_1+?-W^>2 z;uMP8{ucC4-Z`=$`do)7Iy-i6SM>6no~~OOlBu2|VB=NYXyF{xLb~xT*8AGKQ*nhn z*ug4h`%1)aF77M4iJircF-rAOZ7&j zrb~*-_oaM|oG={}CJ{{ppc^n7yswN+<`JsoXFM*Jd=RjvZwAB?AP%3WO|R<{^!;&( z8;ak6cNExqLuS0yC@`XdZgDymMnp|tS%?=RGN}PCmqJe$IuuU~)-=>0GNAmL)q!s! zA8aZLI7wvzBf2J)_LOMJ-TjHAWi|_Wvyb)T`vzHR2zkf)u|jdh7Xwi&>@HUCOHu2k z<`Ap}`DTM7u2lA;^v@?xC-I5#16!l4m>$Op!)U5vJ&Y@qUPhzC(q+; z+jNSQI_0}uzm(#1zvV7Swi9Vk(QXR*y;;qe&ZVbg$86rPk=-ywASb8c!2w<%RfD71 z+(kFUTJx5b{<)lgP5-b()A;6U|Hlv^!efk)QxXIFm8;JK7b0} zes4f$swTAK?J6WPL`O=YNQNG4)^=I?$yqek)l*WMAxpkYh0XkE)UnJuaQCVIya1Jt>q{XQl<(qb~m8fq}BWP!fK+>!EjRxn)o0@HWKQ0dy)|^hirZt`>V?`MX>PY>uUN?=cUS=Lc>Ypj#Og}Eat#ZEJCf19Fl4Bs?gs_GS=MU z>FAyr3Jx>3%lH0y92n&P^5c~&f|7NOd7$q%VfG2T#g5s*mY6hiJnVLkojrh-&gwLA z=)s&qSRq_Mj?7CS6~?^AQ?*^2yXR(~ppa*bDrEz{?%lR2>I@QQT-;4eGMe#j`Sc%l zuZL$MzBx)}&gcVI~2cJ%NFTNdqsu37S8nM}EfI&ns2 zv~*C}^{VZx_iq`K);op`YIHo%IH7)gFA&eI;ce}YXdxYrbg%vyP&87lK0Po0@AmAeu9=9B@RqBr)MeI1gQL_Na~SPT@I(SuodIPyXqjhRIIKH+QkQ&f{PY7JkS z!YHb0mitTMyAaRQ)!A%s zX&Gj+Xt58tlx(hX!b80C8zR4Z65nd4FW9Dy%hS>llMbW*Ew-mr; zIy8+DYKS4b z)kO?j0$2JprzTHOXFRpAV!H9v2`gS1%BV$`rYMf@#NuAhB@d%bq7sB;#bE&tFFyC0>X9UF2pJZG`A2 z#CRt-GKcgzsg5F?ngrnCoBy5wfGQicH@GMYa7=a0DEB=s7^9!>*(Rg)yT@gSO2MmD z)|B0Mv))*~LpQ5c^J3^Y%F5P7LRp5}OCuBjcpTY5^;n@{#hU!(6U*4Fc#rU|#7z&3 z6R6lP5*HK5M7@M;UO73nXyci7ODpUiW@ipi3c_No%|H=st+}_%sNB;6*HXy&?xZ<2 zm0htu@N~B|Ad@y)rt8Oi32smnDytsORkU9)IZ6LR!t{kcX++u@-rU zsFc4-Ms= z2q=RfOkA*5$o_#}0v_7oY4*36r_!4HNA20~RsL@|W-P=h2<-h>hvlCHNMdI1Zc?~- zAR?1sWy`2D>b8GgtM?Gdgm-ohAM8fiU!ezu2wbL3$%j>w)pF4zE)IxF39tfgq0dJx z@(A+WmRs?+KUmU1W?Br~=#Tt$1baq%u1gsjBM9+G^ogcRLdo*0cp#0CsRFdMdmD}g z{~Bez*)lkqa{nz1)&)h^(NmB@gNHg8DzoJ3lAXl z6<${qRlTAOZ8J#N#OAa^Lwei3#-isq{4=N<3mEbt%lfk0qX$C(C8FA@?#u7j!RwC5pEoc zS}}7fY$QlBk1aO6_$BEva5ZgA#EttRk7K*=x$+aopcIhIb#ujX`&$I&?9?v%wK(!O zB>Y&G?~8{`=iH~%cW#BPvJfs})zk#JVE8Dik-L1(9d$)oZVGp`5~AW`aZhe=%7!W% zbbXTDFF44Nf;5U<;ggPXxLYUv$dXb<$Cjsg^}$%gLR{=1Z{5mI{pVRK{Y*E>aAF$j z?S_NY*ctRFyc#AKFx~ILt`sX=S^ijmE$S+n61x(FM6t{fl(!;ligXV69z-QTJL0#$;Y(K-w($o+q z3?vQh5};_RkP?f)Gi9DGBAz$9KgdIkWw{GjM3(Ix=xT{&QoUp?fBHESMcPN{z*HWOJ)QKow95 zAbF_%&gzq-ew7th&+z0v`%R96_Mr1L`nzkyVEKv(zp30LRy-TIyYF+*QUCO*bc63Q z-Uol3w@QWKT$Az!*r3OrFm1%g zv0g7vZgAA<<0C1Wz};9|AK`RdD{TVJwPDpF*+Ro1re_>o4y!j3YI$zXRmOi7jbVB{ z>dRZs)vhyZ$p!fDZ%k)U-#;xkO7vJC!qH`_B{4Q&do!R6SW*ugV2c%&yHtp;iB}$&)eu~3qKGLc` ze!!({JS=H_p@4^~D{+Hq-?_6r${YCOAM)fLTo3D7gV3pwfnZs7Dd8HJTb$0X&b=rC zLKW-y!iv98;T zBrdy5@Q?EG7mixxMw>j1BOM}5(-o`ZR3<2xWepPFR-zH&1fM_yj;aPx`MgnW&ClNZ zyXO99iT5MSn_|OP&wppg5yo?{xZjJ{9KFa3hK2ijexG+8&Q+vc^qXR?Z$n048xNM0 zK;d~JNHV^~wW5Ce!q6rC2aWoToFDZrK-W(O^sHZyTEVY|kxOnYua}GAW zzmYhxu#(GzAIbAFY0ViN&qE}>+L-cwY8tr`2s*zm`}b%vB1#&LMYxG$Say9HM5A;C~`mEuGPQy6@S7~2M7lF`ilpe zGbzNb*}se;ixPV%Ct!+rV@9z?@l^=+5O+u2sBjNi@Pz7|cx;o2yK* z5DO^5lqBm4z^}#1Lc3J4OZ%&NY6#@FVt8#kBM+yu9_yPrn_J=UW94OFa{svJe=+$10DB3QyZ=oby+sHPn^m5I_wk);rp8c@H* zk-Mvm-ua}zq34+qB$`DTcNr+EKZ*B>#`NW49sNV8W;A)#%7&0knEG9gwPCGfG;sX%+idodu^!VAPtUY&rptu-?2mk~hw&7Hkg5Hm zySFWKt?WilY1bpk8#`+;TmW9~Q)pZ$C7n&R+WUxw5Ywf%xL?c(=q5LoeA|_Ls0x5?~i`exzB{Zj+1o-R%`C%z$3Tu8(Bpso1?<$b}!2@KT?Cxt~ zJLYyxg1uJnpbvCHHd&h>35!iJi*=S3dJ175J2z1iXB64$KUOLU2cMDEAOP=&_bXZ~ zcSk!e_937Tf9>mj!)KkflDch|WF?fP~2jG-@q@oRRh_~3F;{Vck$=yE(xnrj1W3{BM2BzI<+T5kY)AP z&#g=O^}ZJzo39ijWi)mCqA6o>i`zZhq3}avSN>ENVhV9<{!Nr_6h>pUjfDpip^7;T zBL?Vb9KX%Q;RW3P^6KCw)a)7)Sk z7yuPeR>@QaWNFfIZkBT8)zek2_r@@zx@c-_vcH7;2EF5ghVuYK!8ke&e|U1zGDp@M z%yiSTIRL}%evNA8@n7mzZtx9*BR-_pxVo{aXY#!b9^qWbfVX;SB#bG9(HFYM;Ii7_ z*c*+sTqD8m3UDCMSp3ba97_{%sugJUt^je1BE4nLOCYIa+KJ^;zHkFFzSpk2scLWau)`QcsV zaLu#EA-)*W>RTJj7X+e@5>6dqhTsIKI#MT6g*E-*z832+-tT-nQhf!lmjon#Bq@Bf zgGNcJPG7^uDzs24wCjT(qJR!o8};&_)SS;zA2T}A2|yP4KH~x{7Ezo-7VEHs|E%8i z3PFOVpA^mo^@$=;J?Z!Z*rE?$i};tq$eXelYd@IWl97C3jAWmd z6?k3}&c&Y)JMSHoUKJ6Pyu?V!G+&Ng=ZrEUiblUQRnkMP5nEY#>#-@{Nk$;{Q3S2k zqZydGf0W%v&-w-2-S;&apj?1o-Ko{jSHgX!Q z_3>|@ULOB>MaCrM1!($Y2gI&av>Kwn&uBYyuwy;$C`ZYgF^{B`_$>vS0%=LejS+qR z@EF~BHjwl_pT;Ybh*?h0FbB>x-yMGSDF!$gt~MV&U_(g@GYau~4i9fHHJ12!3<*1u zpYmZ6gh5ldqr3iw0ve`E6(h?f^23K7JA)Kel6_q&*VNF^J~I|AwijixEn+#H8Ns-y zbOD0Vmm~u$|6$re6&>swVd5!n5whGC0xumGv4*#=tl+z~1*I6^VVMfp1Q2gbMSl~% zYCK8m*U?KuVE7)|yfh#)4jY%3md^SWK=T*pw!Dq{+8aIB`Q;vnMGU6?c_>3*PpF%4{WS06Uc0VwPKudEKf?ry> z&A`YpWSWuS+g(`xg-H1b4$*H%1OllTp%^9yNxn^?gzKdan8BLHQTs1d_M(+bs4O62 zl*u6xw>H?xlGn?H_jkvUT(|!c+DmYD$P~U%BB}&m@QK0wy3$YFVBN?|KBUE;c}^T6 z9y(h;nJpskb3$cR^|%^Ut;x)cm9<%e8T|z9gi$xjGGosua3Z?j#jwMHID3nnSYB8_ z-9?Sx4AM9%&f%T3kuWqwygAHEhE10fToUX{gOb2_HxGgApBovG&>yTH zHLs#>ljvckybd^9&%-kV5C8@(%Ge`;2Ea>2v~20oY1|D8DA!yAbD?!~H*>;uO>+AZ z_1B-qwkp4oL-->gNwQ9GwCus4!Q@mn;Rbry7jG|^F1RS_KpL=H0I0&IMpz}!_-qJf zA2}r&*WAqAVb)g&7HqLi4LrYJP&cdo=9GAc@fMtdtjttGoP+=W+dInDN`i9`; z)kq?}A0&Vr^ZlfJZB>9`{*C&ZBVyL2>(}&~6!WR|1>lt^p1+Z++?s@IO2tzZyT%^A z-7rXF7^cvl%SWT$>cPR>HNk2LQpJwYz|kW9-gWj^t4 zy;1xn@4#D}C&dvXJdJ+~#!4tOedb#_0j@A4jU_46Zfrv9GLRSxFo7uqP~@5t2wxwc zOudhHy2twc8qgq?WJ}pzbr293UU8vXxQc%=&bvD?@=DfN(G!_%EPJl2b3y|zK!Cg#4Dw_9sWmJIK^{wo!dsoeZpcd^7R{ru8s!VB+bqTsr!>#u*e(cJ@GuM^O!z2LfDBfGPs)_rWWPGa}t(&SXuL-}% z-mtz?C;Lg9uc~-)*1#B}u9Bq*8dby*D-Gs=+gkJQ9i?S-D1MCVTh+9%b%}Uk8a9T% z9KA5Ybyu_WK$BTWpjHHwHpo1j=mo`PCe`HTQkD2N4~y$iy2A12in)KW4_0(E+Eclp z>PR`=1;qO-wX7kebLB9SSaXJ&IHf$LA3h0?=UYKxx0a_73ew_6WYpNL4>AIlMuuL$ zq6MygmMdz8bEuvF4|8!`GU>YE?VDC{~Qo z*xc5|OP@YTe*euh7i=ocV30L?kbQRg(f-|%B=*?<#W|$ z*(lneGMM4TJvm+CcsVfS3C!`n%_qIb|MFvakp{qC4r!?ECs<%6@2B>CfYYkb-^#7{w92ZIwFBjOLZvYvg?GY)ZsweA$=b;+^}h z^GL4Zw4DDDy-1^1yoNB3hkBI6cyi3k;5s(U81aN<4;VlD`tH$ded8!v3AlhtRun*a zqe`O1rtH|vF&27ABd=#HA?o25cH^r8e^@zyYVbIFI#0SU??QSPnUMX#9QHQ}@Bx1Z zHGA4VlETpeZ=yr=34)9B)GI*d&QbD+yrTUy3Lu%_ss}QUjXV|%DqauPlfa$j>7Wlx zy9@{pg^&-*hJ@?gzE&pU-oZz;pL)V-rwr}afKtckRs!l`PBoBzv|XCDBYX zfm-^zNcOLF@i?WUm;*bz5k(=RA&gFa_`GbS{2%Rc6op%xQv~1ebsOyZc(yUt^C;zB z02}CuZEj~~@B3-7WPs1Haoy7kWFpk~kmb4c)Ji=rUbg%y^#!ndQQJTIvNhrR{icuS z?u=T4ka=$O<=XYVt)wT!)+_Vpyovh`!dW<_qD^LOP(aEhKE?gzhle`^`zMS6a!jU; z)xM!eBW&DE>cy*0PU^+Yl{v+RgG-MRolzJ*OXL2)Z7;e~0zdldT7}+x_Prdp{MB-G zWL13VI8z@Vps5_IABn%C?vi-Ay%XK{aT84n#*?Jsl&&;eK|i&3Hz&^VDDOy9-o@XQ zBCcZGP<@*5dF~>a{AUFuV+>mZGvdHUD|9)$C}C@hcVHeR{>IZ9Ty#Lto24oq+qm`M z?cB5X5k(n81r1!VfNp{y4sv_1qCSGWmTb@{Gd{F;qEI5o75&Y*vZv{wW~|+ck1XEF(0J=F2Y*V&-Dr{s-{rDicki1w6*ug}I8Jrk(Jyle z!oL_*JcOEmuLCIV>Tj_n)0=BXPWl+|Iw74(^hq(g08f0P=RLQHu6Z;{) zH!s{a=UsEB9_zry1d1PB@=0ilaji*1xd;XemRVq)6^uw?eg977e$rv7{bB)2hD@eU z-_#%C5)brcKSMQT@6Wus9N;`R3~ezKY;@+ZXEO|rmSATmvEQ4 z9xiK*pRN3w=rxcUS1%PccrXt>TL%4ij<@@dt*I9!67f};JqAbXrSf3Y2L_uO#C15| zISX~-AIaQY+^@Q#k24FnzN}@mU z9NhL*Nf8Br_TIS?XUFmd^_hPD4=WhZKTT+~Yqke9>wnzpju+@fJdCOI#WMXGIZMYA zs_mg`IgF6on)EOTO@#8A5)}%64&& zSosM`1>7pg@lDa5q^6<=thR(wA{!DoNOMs~oV}UuOXR*DGTw|r$X6EMi>Iwd-kx;TLbvD=fz&r%s^Mx_yy?O2iOgMGy*F3* z0Fr3|6a$$K?kkL}?brXvUaUs_dqgavpKqW5msOxJx@}xsOiIw@U@Z2B(cAh*Tpd9y zLNnxCQ4!x(Oasx{lfi&lWmBR11le7_x83%6?O#rk-9}KgYw0KSAU!}y52wWv4&;KP za}@HpK23MEErQw3XONqi7ZElI(D^qrI-+9)Xst%+Kh+;BoF6yd3#l7UD*RWp{S&?s zrldi&IrsdpfM&w8{a7*B;e_KW2_V@4gpl-PmVLsF-8$j9f5L}174Ha4o80P&`QNVg z{3CT=D)EzG+IK#85BU>ue)5!VTZ+p$no{W3yiCZJ>~8RHakr_uXbqp3Io~je;T)ww zwY;_z8Y?N{jh;H;{%k(c*rKeB&3ve87LMz8Q6T8 zK<19~s%Lg&|8w2_94E3LB2LnrZ3jTfARN3np>puv-;}w5dx*UG_7=guh|3>?W!cQp z6y6r*-$AIl3}>N$G^$QjL}+joC@Qx@$;iGQ99wK~tCC5EP3J4WtNu9Y=v34fMiA7^ z0P!2XSc?U^uM&N>jqM-V9F$SszV0j+KW{apTN?!-kh(x#J>v&0zrQ|#)DNOK#nSKg zHYo+p#L#FKOY85FMG0{YKkd%-lzpbgwC_*?;-4OoT$J&S%X4l4t3mCy3YT&WdD?Ro!%ty`nUdC z_7wo4Ks2Ui*X%v?-Wn$JYlD>$;Q*!r6wc_P!o;q9<<}xdsARAB&JI71pIE2=7p%Jx zM|iJN*%6zWc8xU2SF_$|HAZBy=c^%$vuYc0p1YynRNj8ignZ_z+T2?r8Z2u;nhN6i zU;p3?`Lo*`BR^HbTZ;2~e17?xP|S}%sLZ7@^K6F{1^Z!He&a2%J_|5O18mbwrO^TB zy?o0(%uZ&XA< zITsngat68ylxz6-iTj(Dl8{E1L{6AzssLwF;?MnC-g70{Us!($Dx810YhjVa<%sdDi9vpl9h5e=I1`w5VfKdBRqR{Ctp{RP>d zntxSF5o2!=Udu@a8fF7Lcm#YnQ(2TF!RxEXmU%*UtPG>rmv)0LMjl8UXv5n(sI1;k zL|Sw5!v5xwP-F0u9^%JsQhNUU>@aD%S?Vb0)!;J>Q8=k$RLcR0$7P0Ia@hq_ot z0#DAA{`D%=bF&aqmkUg^oc?~)BBaV$;k^)W()#z`&S}sq^4#D8sux7k?iQUQ$c$yj zfvIk^p&5op`RywUPOqq<=#n4LVqbnP3hUVXxoGj=_U$KRitVxkQRKoJy?@XWFD2n7 zE;i<*GIzqM!*fPNW-ALPsApVxnt0KO@uc$f|z6Z_eW$pK2*+h>P=l!?rn$`RZmS z8lxYdifSiwihS#H#%O4-ZBIq~dD#6j!t} z`Y+Fo{am?oWqfEx&j49e+j^qp+Fk6>l?U`d##O7#DraNEN%Y~qu8ERsrr9By>(R7-}gOC=g>8Dcb6dDB_V?# z-5t{1-5rtw;($nlq#!x8fC>WA-Q6<4^Wy#ce4n-EKh_$~+ z`rjXtopF@yDcoFX!koYZiaD?6I={ZTdX*hDQi&@|FCSwx(WQHKtRI^)BZ(q!8>Ip= z$RXP{a@J#KP`7-m(bLd4=fL3AANKR7)U30K9EdpfhNw*1m0Il2v`S2~uVu+^?nd7m zTc49ov=QgUo}e)#VhF^@pV%vR+m=uMD;*STa<-)kmMB74h zB)`?t|KK8!6Ahv)%j)Qq=pl-hj*h07 zAh(>lkB2y^tA%9o$PEkhFAu$N-|Ybztm_Q&gaxmFqwfuAHE@2Y z%Xp~Do-q$*)}oT%ceO@m|0xe@nD|*lE~(gJ0N)-R1mjkR zT|Pd(s!h)@3j`2f9LblN+`T;9Kfbq?Y`dvOmBO-NhmdbO+(cmPTYeLUT<{ zf{BT`eba;#^w!>;vU-lqqeenIONrG4`^jkml6{E5QAsm8ctgm8{8EtiD_W_77i*2zOm({ zg19mU-L_DycO;998X40Tx1gt3%|ggN`OiofzzLe@R5|AA{&5?s783o3$D$X2Yoofi@bf;3G)_luv#=iFW9j}tcO;_!q-s?wcR=^;x z8?A^NBLcxXhZ_e{Y;H06zy~rVDX2%^fLE;gIW^VyKO3+28{IcyqOfOo`&}_;F{cWR zG7v@_8kJ-~5}Qb4k}_)H(WWFfXR2fWXy=q|n0)gYZm)*trYGv*mp|lV+TRzArr4m0 zdH;bQz945`3m5b~)hiN(P79Wci)KNjv$E0g)|@)CTtEC(JG;R3w_v(9E0UDdtDIp} zQodK8^a6upN#y5uwMn2n!in@Ud@{|X+Euao2XRI8Vft~4icNW%fZ$yMKsfl@y*QNsF zA#cSIEu#?Sc1sr68(nXdG^vW|;v?IV4!`u?*G2YkB%OwyNfik_o1^?D3o<$CbG)s% zI3QrLFJBdf&uA2=&9`un^ZC!kp9WKY#i>6HY9`+mQA8QP{bfGAL<@K$8Zj%hPJBYMf z$nnr0Fm<6*zdDbq{fUxAeZ;K^67lTwIAmg2=qX`pSj4spFyB})T zC?};{4abPkX!&}ud8^vUI7YEGdo3^n``K?p<9*&iS{2WXCl-K#4Ep0c?MRTRBgrQh zKJ)ugukvab5jjdKLa=WnljtzW3)@aBmB{)7r=^qu?7l=+lLbt$D%h#Ps>yy;?a))2 z)xm^YpX}s^%1^-VBh}+dK9`0u+w#|DG9YD8MWsEzTkASzVca|Z<21CvL!G$^KN?Xv zRhG+zTkLt9d#}rW#DCb=}Y7J*TS?&RDAh} zgd1FLC%!6P?a#0Yr1*Q89`iVaGr^3xoz-vyv<5Bev0)D9I>&GXdwQYY2rFZA^_7b4 z8LNSJ5AvK)PH%4lI&xByqr}n`-o}fc+*D$GujY8m701`GIF4mq ztoDSkR!sU19|Z<@r`}SjRgPUse9D5nACQvj2R@1Z)WYV3 zyh&*nJ#P})%gO#Fo3;+`&V{LQ5B?*6*EVC!NyB+{$Sh+U#fPb%TlL#9n_pFiMBbl- zW{+=^-k!F!$ne*I)j@M&))&=fQs3JhwaOh+(>KI&j39<$!HS`|$0_ge$yv;S59GZ; z4M`8TqRT<31d$twaP*}vz&Ab#t-e+>@d%t7#BNLHVW4l(iG+b{Aq~9ym)Ic`fzuT9 zGfHvbUWD&4RBDn={-xUIa%D>lo@5jQ7U=@j9abEi4T@p(D2A3QI%5D0G-UkrTBX4- zQNFTj-OyVmRR4_-!E=}${%wfXVP!oP;H~a^Kgdr@!79}jl}+4cl9&JlCo&EIp6_8H z#~Y}NaqnBbBq+@x*abxVvs~P7Yj(sPlhf3M83gbAUmjI|oNn3(BaTD;HLx)~g4xkU zNMdg37hIFm(CBs^Q_PMcM^Ff6VfiMcB(G5NY3(y)vNHSQN9w3I=N~@?`np;^EokelK)LOVp;TjkHlXTUCKij-_&0sIL?+{Q{GGi;1ZV&xUR7OwGcM+3EXjx`3ThxpBGHtP z8aapL$#9i{kq$W)hSKq9Ba#2gY;r+8 zbL22BB?t)!iGRZg-C65QX5+g*R4eT!_#{4Bq9F1Z+fO;`rHPg#Ks(jyYO;%1+5HLn zW!JUq6rC5RnIaPrV~^Kg?~keu_b1O0b#yVrUb~o29&3Efsk*fUhC3NE=eoO+iC%U0 zicXeIYPReRumkMPL>|D?Z$&}j2X`+`2Srhh_4^BV>C4EkJNT}h9zxOsBtJnC>qF2s zggr^S{2=4tBGht6{AAW>9(cR+HC3w~*d)^J1O1&Jx@qDsdeK26(QgG<2y*b8mH^sK@*nL^nCq1^ zo;=tKg9j=ZDaVmoejb=uoZ8EQ3tg$V6Y4lci5ARmoK6AShL#019Hu~*5)6DL7xxTC znETRT3xZ%0$1sa_wrW2;$Ih`(`I z5_30BylqvyIrUwOk2}JR)AgBonl$X7LbEy;Oh=Rbz%-2Ocb~{e&+bVD$uVbJ^0#_` zcMNDCRmz`~>ibcXc?_}w{()jZ^hinG#-bv9^A}~{D2Kx@IEWyBKda#d?G^^w_lC8> z%M2m>Fk~!ywlC9LoA_ul=qg2Phx6Jr3;sCDspDZyYi!rGSl4BnNgB!g zk69gZ|A7d9U|TBLSpXGZEGu(oJBUHwJ1R-5A^1l9P|AB*W zV?X+PVvO+cNUn?AA{U)XWjcQZ%PXgnX=dgg^EuoXg!aOmhs*7G^5}N)_ck2$6$uYx z2p2OLdzdkk7cZ`zUg-nAQvNK_Ub@Ex`s2(B(8W!993AtEl_AYW#Y;DQeN$>2UpdPV z0Z~Ik=|9GMUY3WN!&Q~x$x+|G%sKDBcp2IxfF1P{`Z*n%g`vg-Ao-N7@u?HC+&q`x zVCvPt2wr<-fJVBv5!6jDA^_?k7H^`_^PaTNG#!howzpz?9zN?mp-fb`>hmZEkO3%Q zjbrfqNLgpn$!p-Pwex;{?fE`V2D^ld3vZp;fuxk1hHys4(1XK+uk2S}Ntwv~D`$M!=2C?d`&m=|!W*js)_t_q@QS}iwf z0#iz6)2ZXE2GVldzj4`#H4MlAwGN>}w9G`OUh>HUJf&))Gy1UJm;cDdC6&>l6^iormZdt|Jjx*-blRd`Wb^yoyi!dy9YT9=ek=5p7aXL)`kMW! z@Yi#6>H1~Wc_52;hJUz7_o4Qbh{}62ei0bi<0>+iloa*mfWVTvk0@F>8?s^q5@o!+ zMZCfHlb9%^ z*jaNm8-hopv0Ri9ZgUEvoV3h6To4l~_qlW${Lh`$BN2HQu`G7v{`e-j$2V>h8|;EzIW29=r@*oTqqh_d@QZn; zUxKD?K0E%gJB(g-*Zka&N|q)k0b4dU4v1D53RX7b$7(uJt8qebgYCrU`DM>#S z<%Q$$%UMPXH5H1Bt5xXql}iba=YP@C28U$WM9CiNurW^`5HtrwA)uZIP^(q4R!31% zM-c-DCZmRY-mUGHI%Ke=acq}jj&qwI+XJs5eFB@)-u$;PY7{^TvDWau?LB2%x)f<5 zlhkz^EDB9fe0aRv=bLlJK!v`VL(-)xqM$_WdN0K;L8<&u6JBH`qNI6E=@W@Ln&@4k;V3EK1A#*Yo6ttNg^t!gD9l%7bya~#tbv!0knd;s)kfdtdX7M}K z@+guGsS0SOhZ7_bTt+28R)VEvxEOP-bjRg_~w{HF9ox@`Tuv=1XN*g@=r* z5}PRe475DR;YXN3i~Vp7+S$CJGymm}f`vP3R+z$l4Xs27u=r!rUC!82P~1!W0)_Z+lMU0M#rSi zj##)RNV>R3|3xRJA<*$Sk51Wj(XOGLATR7;qM2RikB&9z#|}Zh#81ie$Vmd%EAjQ0 zrYbq=hSVj~g^4D5+O~0G2kG;eAJg=P)JNR;ATJbAyju=ob)5z@Rn7d$l^T0<`GeE4 zEKVs(G=`}U+M^Eb9Slr928_f5Jq5=r{7KIMr#A;-tA)%|C|ta6G1id^8jKTDO*V=b z5hbbaRSgC$s$cUAC23ur!qw|SoA+zCxSD`k=HD6thy2(q)Nv2;?*hsGS_t1Dae`c} z7o|7^%?&l_A(`IO;Mz9&&hgrZJ0I$ z^xMyi08Mk(Cy`3}h3bP%1v%x(nt%!DOVwoN0SwFtJl_GR%Il+fV4#->Y*%SPhCSyy z(@=ab{AEa5QIK;joxUSbp1qmpSt%Hjz1wnuzc~4XA)%1vQWkuPBP7)v6*d>Ta-8id z>N9<@G0d70)MDBy(@a4>v2Mj?^{l*Wk`*CIe0(VocIYw&J2Bz9=n9MgB>tuP>LkD& z>;b~xzDLESEwl*wsN9hIn#0!5^7F2DU2TTb3uL({aIc>nK%u8c+;ORMw>IP5f7S0g z)^{h}&4C{)zK`!U70i!fpdv`sqAF%Xo?&VF?|JDO@^a`}_k|hx&WlFRI)!ClD&FYB zm6puaA z3T%h&JtvsZ{@~x%9fT48NXctX))#v#StJ9U?)a!tpA9*fh+Kq?`E!R3rShq6YBsH{ zX?Piu=3z$XX|{p^0h}Z{wyRG|WX;r%i!HV5prL}t-$QvP~4x9}Kvc#1zFw)eM_sU$keFn$LHchvCK>_P7XrN8rzu(7B#!(d*o z=yf`OXSZ0tFfBjR9bwQ12;yF{cQUQyR1Wh3JA1h^S?+qNN&Gw2!#!S*@obOqZjnxT@F2hV zfOUP0W>=>DPh!H<6o#=dS58!!W$61{)Tnv2FgHk;dd??umbj>vSZPfZeSztLh9PM2 z3VfIB)2dPjNDWQ49II36yiM2OV3W(wx|FV)*q;$`yVDu~^8hIb;){p+xtsO>%f)u} zgI6a`B}g<*TUmR_v{P9G0qr1Jc@6LA@2R+P_2NzmEE z41e(#E2$STch?AelWq|=7gAzyfd#)V&2oqu5V=`~X3MypMXu*y-W^*)<9}#yK@-s# zbb{P?qEJhVN;$&7+wZTrpt*7hjM85$V-+#74K)s7VaU}d`leq5q-W_gf}X1$CfElK zQfgq!s1M+O>9J#6K&KXK3x$4VZ_Q!2l*h9zJ%fzsXdMhzt}|O5-*X3K?C@HoAkzaO z>UcWVwyOwH5Zp$HMoNRq4x{z-II(*+>wne_`MBdrPy8qxIDgyeux56~dkq>UTvaBr zbHv6Lu3O>6M@hI z)K^f<;Tb1BmEv9C#YzuUV<;K*07)AlnCw@nT?qvZVAF|%&)QVP7Se7^VQ&?t?0sID zdbTHc#-#s5G^J;z58Y_-P%@LpZ8jWslg&nOx83tm8!w_oMZttd5ahNe4)pSZ2{3*HwKMnjG?oUz<;$P+~W9vE0tw9?`%s8Z9t!EWFZzRr{a zhRc2g{?}iagp|<9`qiJ-;d@hOhf1c0Z|xbPlvGwNyOM#i5r-F?S%tHd{qH#Yiq%)2 z`jub)g{!i_*7$l@@8lm)YqS0z-uVVbee(l8)ZINN0%JZIyG?Utbpu>so|@wd(p*W+ z3pQwxNP{w!gjQJWc_S+cMpG>rj=EgiIR4bQNXnuZqV7Q%Y$N^2Vm>CvZ%!L-H@_Km zAT5Q2*;xcN#=afy*&g~8)HOKM)cFXBl9HPgMML{nIypi_bhy%#4#<%`-_fiAnmVh; zcf^5Xc5NqBwA=naLv4vPKu?(~cJGe?X7gW3e;>WQxb6&M`a^{M9LlfTU0UDK$8WARmU7w;#(W6EQ^@Lm6zh>!VgE#y|0)sNki$GX)vC z1EQxJRp1b4S=nkc{M+2Qus@0Wx- z1%eCd(Bk*OJ7W^dH|(kjr>c?}AO9C0(65<5)mNkeF|{sDt$0^G`*Y7! zbk7%x1Q2A?EE3t*#S0PoaXGaLFW>IB+wl)zH0&TehlXZ_4Ca{Va>q*e8!8&%M1qdI z(plcs`;_zssg^X0m^COc%JB5&yF7=h_#%wIJ|)Ca-?Y}_a90TEajh@z@f%Yqkj(MN z`0k)QDhJeG2uaSXP{$6T-|>p&0RjRj1gn_@tgM-Shb;xg7H{bWWh241#I_qKeCU;I zsnop#qx+)U(HLSN?96N|pFS|!K>M-&T0@3(1-bkSHs&z$z(Cvgt2ncB#_ZZ>b6zQ~ z>Y=;vPH$&&dCF31RHk_4hBSVG7d`&CsjPp;_I=fcMsHZ;F$fGXf~hPHpR?jrxWRMB z-mYDauH`LEqLbhWS+{M5z9P`CGwcQGzs^LFJzi62)^o8D%2OeYxVp8NT&9k^j-r`$ z+G6y{a`m6A?E?(<#i5nM@52-r)BO(tUTU?UVb~iJX1!$rRu*2rxuYC=9$n0PX0;wR zpQRJcdWoMDEvfa3co^u2L_{WP*(egdC5pL?DSn32~`M-8Dnkd?{-OPq{S2o zQ6WQ0jB}IfmQUkDi)KAviOj=n1lhw#iFN-Mx*mbzr#?Ps2zBc$R56G=j|NJllLWLv zx$OvnCengdOQyX-?>PaS=E%;KWAF7RkKe@WeKrt>%3mZ~h3*yi1sR3V0tpg8mIL4s za5gPWc_a`@K>DQlYpNJ30?Qt?Wl2>#r(l78r^?hR8XDDj;EGLSi`fY$Q7?03Y)@}v z!eNxh#Znpiq zGmp$u#}4b>p4^p3HVA#geSLOk`=Di(*AhgWz|P|K=?{JN^yZXedcZO13GOasFRyi> zv`8P^n0f=W;ny!$fK?*I1zc5iSyZ~jt<6&*H24p^ViD^J{bu?n)fxQG%iRmVZ+yxz z`=x(SMsT2r$L1-Bhog<~`VI1ZHa7}wQQwm~xYdBod$???x7zlATr-RvKSMcE?nyT$;u&w#?d$>#AQTU$+I6i9lTzHOW$P zg?@MGS=2^z-|UDIJ-r(&KWcaWX7oE*PI_8KnWto^1nxpwxg#~3H7ohQpe`~U{J|;m z_D0rp<%xGAvV_UpG(qqr$3D#=r{ zC|?b2499elKxO)BV1){-;nZx@enwQ6C_P@fR}zj_X~0B+Kd$_;fnwcev%{8(8n!YX zeNzfRw&H=otjE)4pqi~Y$NQRip=hAHHSBIf;JT`{-u*1mtC0Fp+{dH!|KIMnbta2H zG&;kva*oCuWLV+aELzY3JIH1dEa_8acjXNC)KSjvO(K{v%L!;Cut#LV(T)z*RZL`Y z=^0$f7T)E&^nFK+$Z}R`-*cu#Qvy=tVwckb6@_b2-6f@5vu6?3M-a#(3T^7kgZyKG zF~V6<21X{_i9+&?)khpEDbfDBi?X>k8S-ysF?bqMDy7^QBB_~*N~qTY^$>Y&ViD~^3k&KfIhFeJ*y*1`9cpWf$Ld91Cdq-TIU ztO>!zh;4omF!<9mMzdmIPsfUCu{FFb)(${*9nys_<}~)JOaBNtT8mhhGtCZr!?0B zo-~csK+w5nIl3Qc?rngaBC)x<1|-Z@qwT{y?Tmr46yFBiSUr=~b#MEy^HZ=|#FS?Y z6w2{DOhB+sCI~q%rt-wIWK z;QdkO+R5@r{4xuOCP(Xx#pU74{}SZ>&Bh{%OdbJn)>hSmU{f6D5EHp6uO3QvKW<`Q z-=^PhSZYce#u_!4j!RY?9z(S+kcclJUfut*`qxp`S&=f%E5+{M6&-)@B`*W3-TZOn8ax1nSCOLukK&n2aw#?&w!NwtfqkKH^9OZCah5Ihe6AM665#ChilTd z#rN(KjceUI+Dpv<68*<83{Qb-9q^$DiSMo$Nn~&DZ@a$ovtt+!q5XXUlj<%A*fOo_ zIroUxtBPorgOWxT6JUSZ{Pt2}>AaRFGpTdRKFbgw-~hZ^=P6Um%XfRPWHPTnwR@(N zb`_;rfTpW$g_D@I|0nRdY<-hU3hwDeD3)? z7tL{0vEn_;q(`um37Mh|B9>mT5=RPZN{s^ z0Q7`(dGJl!V%A%$=GuwbF$FTpP5m9(*SWd%MhangRD)P~#px7jYw};oW2g;DWQUrl zZEuSx5b}!G1jf#WSodP3bU|f)0psiU^+2b5-NG*0bXO1qSxHGQAsgHf0mC=H%J0Hb zZh^eAX>%%zox;ZE;?;W@V4dIfO~n1*CJG_CD!FHQO1m#-bm};M(8pBqd&)%_6yj5V zY1e6Npg#Lt0;s&&XofQ&cq5U<$GPS8oDslX6x9X8xCv?r2ER-DS`2WF&mw%DVMr<_ zpj3`9j}h^#!q)PRC*31RqfpKW7&ilszLJ~?7E{DDhW!4JK|W!Inka8CRtk(FAk8>_ z&tybIy3C!Qv9+01%1q)(nIi{4<$rT1DKz;uQ=DR2&Y^@Sr=r)v8@Eq5a|H|yy?nCq zJnU&Fe{}xO11RxMNoZC%gR;9fbm4+nUqk)UFXcn=) zlHIx9|00}&I6)v0 zFh1vl(#WPlNy)(yqw+)e7RUAh^X&mSy!(lI&_}Yb4SCE2R>{Wd8DX83(2+1O7|RK#-m5*`|+BeA)fvnPYQy3+*AVAWdJG?&;wPTql3+} z{vFy+GR-r$V(z3wFrf-Q*oEfUR`t#QE(2yA#{f{{;z`1{Hq{?Eq=1FEAU*x5!(VJi zH4sx`BaeAXUD=R5UY9-oHS&L!OJ>L3ib)S?Oyhs=MefWeqfR83(C?!`p3k6f<~xhn zg68`^!r2TQF|o))R#gZXIQum@L1X0kYlLdCDHW~A^r&cqYp5xnc0=|&@6QTth*KG^ z*O8+p{@l={p(o8)K$HFE4501CzyN;b8!L5sW@N0nwOY=i_Ay~=eFY(kmJpY9uqZIi z4T}~7=2hyQhV+0rX6E>Zwg`j#o`nX2Clksu*I;gFut<|aWD*wn$yUw3M8M0RBa!{e z>j5NU#zohWY7-K1w#)T%55L_Pw1CU^yOK{ZPO|B%{sz3A;9nO*wwiirZW{TJxt}xa zw-x6;IiE}nJ|#UePyq*&GZPnN5HjQ_l5NNLe#XM$5274zGf@9zd#|&fj5s){vbz2b z&wHk~Z4QD7A%BnLb2u=kQNR*8KDsR`oa-^dn_9LKMkSLS;V>e@ia? zUN|~h_B@%Nynu(?Z4@3m;0WYE4FZ?zDk~0s|}%nHRy8bnVy@Sejg&cm6P!(E6#hqoc)voy z)p+VaWaMIC^e@7BzUb2p=%s14zfM>7kbrfvjXB6;>Vss};BGQlmp45vGwa`Hagezc@S(ywJ#}bl=Qa0q$YPLGe{a)Xc{Fk$a!&bcJr~zFWe|M?C?$p~3RjQ1+kCyqX7sXw9vC_em zisQFR`Oc8rjyno<6^Y5LrZ-8A`N8+T?N3Ijp8cgfMYcbX$epY;-`-IuY#UXX(>PBj z9rXAaPc67ytS25&1-_#N?n@`IBo%D?s_x^M4Npy(x;-jh-L42p*w}ON5*>=VIV=0{ zMl~Q4xXP5N3o}@JML9N!K7NOs2y-F09QfVRjq0R?Yl8{XG)bdwYkd$=Pupy;r{NL1 zO_L=ONbZxZUX-X&m=sd!(PUXGMceTF|Dgl%K}K8*6QK1 z5s#m(@6VAqtK`KJtt?6FNKHPE0D z5Llx>;M}1u8kh!09*Zi@>pS6w7{gJPFzRJhQ}eaXE54gE|K~l9fpK_e1X9DHJvZrL zpmp5Rj>N-tj1NgsTHNXBnbcIX7VdoA@f}|7=|EU5<-LBvxzEMV!2h9@eQvUpv-Z+W zU1ge{ADnY|)UtQ%#Rf5tPim>lsoU$^MiIMkvln4O+sIfek*$)nv2jsBoxUhm7JvD; zRQHn}xS4~PJa#}xwsm29j}`A6I`nQc+UkDSXCca=7s4@7oe@gMdcUXJhwjQ0_^yD@ zlp*m7egjvA$F0RMk-Mp6m^$HI(0?yJDH)0S&Gqxs7hZ_V6N@iRXxx&H@Sc9ySaQ}8 zt$G4%sf*>?H@;&w`s>aXhNRa_4Nnpf_r zC;aAvwW`2s8dH}kP43eLacH0K1v1qqnDTBp|JkLh$Jmb47KuuuEn=tb-U-s;3fEQL8viyzWkoNJI+GuqU#FiLb?)px zDKo3iPF^K4?TMZ1z>%CbC18B&m_KmuL`**ZTciGRvcghZktW6u4YF__FD+AKC zcD}T4E+_W?NMN3x6z#uONH zm;3qiiJe_}rw*Fg_9IXQ#J;oK28bh{rqX+Xv!eBzDt3|0TAvsIM*XY?vyejYFj60m7ZDFUH9vCatK9 z`?*ETMu9`UilzFhV9ZY!B}tq=AOFFHak*VSy2WOkaKHn1$Tjm{((&h_@%{pSlkF{dy$wgbg#@R;gb zi*Xy!)$cMxwTa)$*@svJ6fG~ z1MCzKsp;h)Xp3X12jUE5G z|3&n2wN!uXEr@m<bcvK9C55>f&l@9i{A+mD%%GKDxPHTXBC6P+%Vo5HM$NpkDvG=dXl5|b!) zhkD+*>Ph^ypXTC9RyEMbkENPjFz7yC8gD6OLc5rucz7+C5MJ~yvB^#kC^%>C6faC- z^Ex+v>r&u%n0{qF>5D@qQ%}8E+svrbx!^`PL}^4Jk_FW zogzy0R@{bsk2IR!!k8*+yG1Q84kSy~;>}DY6k@2Xw#>P?{+rxn_Z9%XX>ZM(A1u|= z2G)g&<@D*lnnl<&P1-|TzuPJ1Zd9{i14mw80O9);)A_Zi`wq!8UA@X++<+U6$7LXQ z&ih!Qzd8^-qMavGpQ6H>Vdw0rT!rG{cc159rOT4+-WVBw|Js8+bbU7c9`|ffP-JSs zfNuJ(M1IbY@d^GTE7XlBx%kOj>b}=?<8=PSvZv@$rAK;;l^ZXc2^m-Q*VX<~XTb{+ zWHpv7I89&>Wlace2Xvv50_H4I*(-i$7nIEeigq(&MtOz6V z^CpZC&;7^OejH!~0=kHchPNF<>gw*hYnMGVvAUH>yu$sqo5$>Nht1 zw($2?uya>0VlJ176uA-I;oK@^WH4b6pT5+wq_B`+Z}+o^XDt>Turd?vt0bbl46Mn5 zRhzOLtjL@Vha{LeWGtIy1Xt62gR_Uw2j|8*@L7Z>&`1Bz$7=2HP7y-;B7>69Z>xfM zrF(%(*M6gvKgBpag-}$KpUz|8@npgnw$RJ@jSiDNudi*(z`UmVmJ;j^UpW$N6^oda z*!iumMH-sqAg#5=S|Up%e3|Sehcq?|FDn*Wh4O#BiEmbxnU@8k3mo+e2o3ZpJa?yXW8W>>S~U&z z_2udXs&Q%wjo4Snc$y~Yw|&{rsA6eQ-V90rDWeuYP9I6!4bbOcE@~Ap7tg=lV&Fy$ zW*Ew?SNst-{O`Nu^4WyWqSvMXb`fR~SAG7u$fjN?#v7(D{zHR&OoOGi#^{4(86kBe zKoT&rd;iiiAp7VQ_U2~RlxxqPVx!#)c4^>|uDX!C{rIN{nSy~DbU}ng7;SaAYML&7P-p=}bes86MO_0#|(k8fUvZmE!^E7#Zizk)s zTqT`(6v0J648`!`h_hFuRAdQNzIec(d?3wlbIr*A@F(Sn63%hiNC*}MN=C&#$@?(= z_?cX@tmQhgkzd4H3VFfar0-G)`b2k^2ODOa-UCePypVBm;2*VSMklizBHx>)OXtH zOu>pL+tNtp@r8-%zi|EG+!HA@=3CQYxA81@%CqbfEg0xd`qXa?mT7^v4lLrED&Ec? z`3yHIR7pllK%xiuehff!Fmk>65A(;+B=oy_UXbdq zw?UIxOnbcES!Ii_-b>pR(J+gnEKh3O@iuyI5|;%AerlaLrPlf7drT-&PXB8^$-scT zu~E$2(=0U@{aWAX;P*R?5gjEOWE@-N#H8&Y8}wC>rTw3k11uD(d22NUjm79EL_WEgWoe%HMr;k(=g+usk<3yaQbQc$|kO~LCI zE*;Do$Q`zS)Q?suQdG)}C>o=laIJAWgENSWQ+F)A=$DOjzTTl~Ue(dKRfvT*P_h*V zir3gZGJh-UCw9hfFUl9R?wr-7%=i!4IjMb|8&YisFXN3ZM{gQC;izaU0pb6a$SP0r z@w+XsTGdMoV)JLN5btkJ8rtWrylWQ2c z@w{#j8TH?fmzOx7a>-)fptN^S>&v|47{dU?7nZLR>-eZ}@!Yg;Ok6Db459w{6Udbn zAD!Ezpm{;UL)-OY`g5*^R33g_T5i;^sKTJ`V9APg-GXi4xBh7CSI>S4$RLAJ2f}?q z)A7|a=JTDK%uu)~Me#qr_mfKl44lNBsTFsM#~UYSH$lIc|BJS_E2$S3JSDQ0;deC&DUYJ zI&$HIf*HyoYk=KNFic8+E7p>56Uo#bk*tIfsI^vhDv`PB5LV<)$fu~x=eyk(?X({p zbH8|TV^5l{=%KewKg8LP!}udIIe)-wxsIPsfB^#Q@yZv>BmV!|yUM?)n!Ybciy%u& zFAYmd_l49_N=SD~g96emNXW9gz`_zLAu7!xUD7Qg0t-l|gfuRBpXc)Z^A}v_b6%X6 zXMShqTQg?{Fyzy6n9h&%QvjpEw~C6g?k-_HkY1ID_6Ggy#H;l7W{v9!xA#bOU@Ixg zXccg4BGH02VqWXAlny#B2u8@L6e|&Hz zlehbFe;7%;Zr>**JzqOA_$$gxEne;Lo*U>X@>{--t=J~;kJ|<(wDeZqXx!`9td_2( z)1|H}$~mhQO~D!5E{aUjqqmEZx{Wfz!KYhHn`h{`=fBNU=fbjEA%=LRPLME`a%NNQ zhkZvXj#^H-1^SrEN2R$ol>?2K(%cBY*U1|w1_~XAykZ(mgUScffv@F{!;0c=D97ok zcL*6i4}6kg;}e38PYu1G23oWnxfuCQT_2Vt)O*P>+k)!4!^^l3l=$m$+zaFVJ*orw z7aygGxM~UterDG+h&limd6&3(r`;Zv@q;5+Yn4B(7@L_f*-~1l9w?c2rg8q6KHAGY z#Js0*$SePPoFo6wIL8c<=f&8fhV~oO)IQi-)gcG{U03#@`eatkO$TfJLU6wP-b{h{ zL~Xwr*fo2n)MCJIZMiBYxU#p*(oq{w?JS@GGXHw{+yx7l?KyFjh>$3Q1OqwK#7Ybi zqu}Zl#nN}eFqwO-<|Q)W)UW9y(dE|*E-wSf&`!o&5t(c!q#6He!}*|yc-vKWZd(T} zRKM7w&-hGO>VdrQ<5rJ^Uv){x75sD3F`qf$E*_n~W};3`luAo6&&D%;-~p&-@fr;# zOcGRN;eQr+ck!g@X_gloLt2Aw&zfKF7NEfY9LQ&rTh6Hu9{G*RZWnKOY#~({u0xDxG|^Yb&yV4_a52{-Gd|U1VMYK#YXiCx}@7 z>T#$Z5Jd$B%6Zz_EFP{=0Qpv-K`b4kmuh<)@AE%9Al#jcel}%Q+-BuB#S?4)Y4#0P z?Ya**Xhb*fV}w%&2Q=il%%A~2Jf%PF?&+&b(8eF`)SbxqZ!c^MBF-pI!WEbAN;2nm zs_GRy)y2+DIRd^;N;(u$N$ytnzIMjwzOx=9NYACGXrwfp1+z=NgqD_eOf}V1U&g1k z2BSoT58;$QhfV`?ET8U6S)BT|P|!c8+N6^G68GFVMRf$gs*8EQq#WzI+y1%p<&lnV-&)uZ=!$tX zu)l7y|IIA>O?SD3@*l^rt>c9?ip+i)-M9HSvI||IVdH<9UAq1zF;W|9r$+9Yz0Meb zecw&N?O>c-3u1ttm+=8!uc|t)_LS`FfBGAP$noS0r;R`vJ zJeJphlM(zU!N)kPLQ_<*)27d4;Ht@Tos@nY9EbGQ3TV{#LbmiQ}#t z6?%Sf2?DhCdt~lFE&CJ9n~$_Lt%NmS>Gl&6_qG0+wqRdqe0jRZR{iAXaKWQ^uC0Jj z5rE|-&tSN|IcU#@+Zd-`KKdpHdC9pq_X7QEPxyxr^|&?sSdTXBdz!y5N{huENbq!Y zI5SZiWo38GEZM5+=3SkgRSL@n9rDcDoB15TZ(52Y&G*t$;6`WtJOZzlv zM{xOM+~*S|CZ=$cDI$n)Dv)h#`t#JzP!EC)iTI2(I0^3`jix$8thO;m=vB~I+Pspy z`X}~L#Ex)kd)0uFcw4sAZlxpSqYZGRHHj4(1O|60xU<2B& zLOs1t&CHmMGHKPR_>;8q`${d%W(d#(hqzCvz9$B@udTtBx*rV}jo!4xy5=jXc#N+q zp*;~sZJtf9ZP-H9^u^X_j5O5bbU5YmNT1|=`)R}egHg8oRw4N*9sj8biDl{P8*I@Z zJLthySJ^Jh$}@LFl+vU9g~PxIzw09b=r~g>3t-KpYe~7=2kH-}w(fofDN!n5c`g=E zd=#$xQ=tk1p!K_=56zue7^-a9>>F)){U}r4|m>L{v zKS^tVe;4pz9fi=q0H$R7K2y4Nda4nee+mF2LqnYB^h};c7;XJ6w~&WsTq|_ibOS-D zVzD;JrMI#h@XO-C5tr$7Ucz6D&Nd~jCC(o62cBVxYM zaNgbWGrx~bv50_YWZHC_q7K6b*A=|R|MvND!6nx}&Y66T9j{nvXN|+)q{^e~osKEL zl{8OI6+c!OqJ;SpV=+`wY=$!t8ONS z7WZsIT0&IB*fc}S>kan}kegK4f&yho@Xj6SgUt;ehv*caf|2+;>I+&#c>0sR%QQ%8 z#pOos!|xYvVO#q5VQgzwXQ5_x*|~JlPw;OeTJQg>yb(5nnmEE46?z7IYxjs)`aisL z;rrqz^|>YIslq3U*2~dKe#JaqJZ9x@%e3MkH7yEG&d&XZzjpir0#pj07-UL1J6@Yj zrV|X}HnHnrayk@FM|-KLv!E8*&QvP+cVk^lKQ)YH{Q>2IHkzh|GeAb`pDxzasiAw* zc{fk3oF*48%%U{up|(MkJ(H0GY0hMH1Jhh%ya&k3SFZYh>&V2p|A*H}1?=?DAtF(L z4GH9kSCU&fXCK;2G_Qo3ySo$}Ty-I;Z@G$cRoJ-(Yh2ud`_DDrydGio0AR!H#}8e1tYhm3gCVd7A&SQ{UoCcLaP8OCS;VU+Jv?jTE8t>VnnQmMIJ`w8^_6&=}#bxNxj) zH{;v^^IctSceyxBKkk3kP^DTONxet0Uye-QV=E2{g*8lbij|4;AalLzN0ND`_=nJe zuAP7&{`?tR-6Z$6RWw?`u(*SyVwKZL<+|oN6&0dTA;LHY7KKK?>=E0}Q53c|E6^E9 z>;Ht;S1N?J!4byav66WF6s$;3V%c$P^Piuw#bmwtfSL^$p#?_$_T=xw=3AHdl)Eqf zaMxwm=;^`wl~?+3&Jh6%vb{ho-sFY~d9Eh+xT~CMuXHJubcYGfaF1g`!qRAF*WBE# zSu!ttKD(w$)WzOUxB0>L5wO!(62w{v(rRd9QH0IRbWlRqWf61WF2yeD=UUs~>UJut z4j-mj*K&g**eDf)h~Eh`zw%F6wo zy4v_)$**aCBpu%>{`SoZdQBYnGki_~BI6yy=ZU#&?|w#PZRKrz0D$(YPI3GltDl!v zE8S8&!G*h71$)l04|C24K#Y!bC=CcC)!d5t+m`NA2|@HoQg23~!FN8vLs3eZ_2OdL zXs|V@Ooe}N%f!~fVFV1-$6EQqKP_uFS*9=D=2foZ=fQSdzashh-MxYl7Kx`pjR&96 z;>7hYz${?(e}mb^PMWGX%Ca&v=G z9TZ}@c3JbiA=N6aV#RG|pp*JtgZAetE#;49b`0tT44IzdaX(fAQS~2cl|HZ!2rw~g zY7uvG3+@J_Vog~;Mh%#6hH28dI=W+yolE5hakZHsz5%`pevzv~eb_#2+v!XK^G4SA zkf5-Y+3GuDA6LK;5Py=YH6#wwx*`>Sy6mbn+VBv(z}mX_lU#S42HQH{q6Z}`D2`E)QMce4;)k+ zNOJ9ll^1i=q(RJazM@}TVlqPJ*Tguevb{{*qy*6A z{N*O%Qn%*J8n|lOl`KeYQ$eah;&i0K zWkns*a=dLDEZJ{5LtzA;E_UHnKMkA>+bKNr_4df_N^e2Zjfh<2RfOJtJ5(mW0`jG5 zU|3Y}74DSPa>dUbvG;&|dkaP8rl_GSCldX$#5p#8ADvw-A^&P8Q~6^VvdfJQ;wT>4 zL_FG7ToNo{^H9m#DkyUR?zKD{n0S^7txts#_jYG+R7--T1PytqQDG@TPOmS3c8&05g^n=;9ZTWUv z%f*Ud_+2|)2O4)^lIBs^j<8LTecqZ|a{V`_*cki@RImWt{88^FdPUnugMJ!+lxUp4 zU!Nd|BVpyuyYMY0Mp60iTkcW*S+SR2F9l#n9g^xbh`;TTj!1%w9bX^A+AX4K@Gi?!9iHq2uo1-kleboH|p?ei2p|eom9w)p?7$?74Br z%R7rs=w462cs3D3>bGZuvu_YxvdUBc7jz>Hyw#3`u zcJ>vk7@9gjJ!{NHF{a<`0v3Ee-U-6GXaur%j_?=faBlf#bl!zG*old%Mw#ffl*G%KANcoS;7tQO#L=oIh`_~$+{I4dF zPB@+KcKC_uZ~LilgXAYf!dHAe;aIcDqYe{vdAE%6tOcSDv=pY%KyVD&8mvVcu%~dO zQu{G)>Vl9sA8shZMyCRpz}^b*O}AYxuHyX0J6_@_uOX3=Vrk!8TTqfUj* zesHkZ9g!Nys4BbzMaan^8mSvcUX#YoRfC)2MaBSA7=U3Hmt9azpgo*gF}B6ZjT46) zIij$u2tn9S+{*mr)LB%k|H)A;{i{%;q*g7T+;2s1vwV1=rlyUJFS+D?> z;U#cEeY`Lc@f{-jg2#+TMm3rvuaZdNRMAOV1gs@rHG@rYnpRef;^se#XLdl8$94;^ z8pJp%bfL*chRr;Z?tC7G<_{fDaXTKQ_f?)pNUXm>4V#3n4-3kIrpWE1J*E1koH0Qw zgKr`OUsGvuz@H)x0%ttaj6jAC`5#*@XY;*o8fs`)2a`}9_3;x&eIBr_Ay(cg<}Sf^ z8d=2jq)mxqFKcgqWFnD=d%6zR&c4s>^|&_MLc{PAwKQ@llt&}OPh=7QrVw0P+sBwo zfoK&jL#lyS_G)@>x^H#Hb*J~Icc;_1gX*i9XT~VHKj+q>zX-%-@cVhGw6=r2b+xvs z$1Mm2;kD`O?}(2c6YzmPQjw~&uij%ifm~+&?tvb?7UhTCdxkGBt1_-wRc|)hN-z})3g0QCMNRnq2V^HXo$pXk=-vNZ(EX0Z z=I@h;uJTIKh)1wk*d!S3=I3qiQ#7v9+OFm%t`>r3E*9?t6el|;FAF;t3kTm<4t_yS zenAc%CU$l~cJ_J+`+uJJ{{-wE&222b{{I3!B(pN_0`&j$1Xmk-i|?)`_D=tQnFQpU zw09Z8e`M4hEnPiKTr8kGJUm!!9BjXvnK)UnI=Wc>Iuj;({}Y1gXIZKD@%{54*%|-^ zgK8)*CGpjB>15Tb%6#8z{qFoa%g|xn4bt`L1P&UTLJpJL;tTfZKxBrLGowYCJE-KV z`5UE>at1$5O4)+TZ^j67o#ey`HIlxHDRP~YpHy_pU*gM47HR+`QV|r=s!-6F0Qca| zvb!+@Z-ITktNueFE+~YL7V3cH^P;1XL$F_~Rm;=qp=gKy+CIEI2=Kq(|JA_%YT$o0 z@V^@P|7u{WJ`^JeAn)klb(?nlCS0}(#UyEr8iJq@+7d_ByaMa z-Pp;d)41R_1DXIi`*;`u52^y?x8JtJ3cLV#Dj@v}-A@Tg)q%&70DU;O2O%1!_=hE- zIQdZp%E1E)Cba}2(ohB7BwfK`mhLHu!(!K&B~Ehp4Bg`eB6r`z2XpR|bDT*r&NTTy z6YxEl=^S;?$E{V)$as=lDdeu0@*wk0N_mjKQFo+IGUB?9Nfo*UQrZNR!Sb6h%r{uu z#=nlfVk=jC2zF(tCR6Oz2;8fI4jef$lJ2mah*I3#qk*g+%%|6pBru1^5uphI)u^1w zY6^yK4;th&ROpr8qi<*`G9u=ctglMGFP?9eWJ^Olo{!db9I)g^0kzb*)HR_86hfRr z3igM&G+`eQ5|X`YH%RyKgj-3RC&h7KSXc#VoPng2q&-ot?Ep#Kq$)vNfvSR} zx#V0}6v8)3o4_#aP=z28Ol~+yV{y(O1W?1LE=W^Qp*cEhGSDc4#)MIAOPlBVFU@&+ z4wbJ`U*rXIu!sGo;sNobRj4evG}e^MuU4*K@rH+&ODopb5pqnQZ8?HH6x6i4|S#6Z}+s`cU8}^Pq+s4SWl^L@ah%Q#p5P z&Ty%yVh#!dLu3Y*DpUf)`dy8pJPi5)Xm%>?AbmidjKvfOSoEaU9dn;RJyvcOiwNb zPX#)EZmY{{RZR%w3XeHwWUz%o2eX+XRUPpI0tekPyn%g$_3y6=uI66_896F57RrUa zs028V&mAH}6H9Q>1M&B(gy6&A5Z>SR#h>UN^ZkWcaJ3-N=1ynoT{|~{mV#k|(3(K~ z!|qU$yL~exZu8U6LRU`dayLcPAyF_Kg*&u8Se$$me1UGp(Z;YY(dL=vu%^)iv!YEo zI?8krTCYOiAI{qt^9QtiC9t(BT*{xkM~5pW!>KFu-5;g~Y@f@Ahbz;;*b+vk@m#?o zKoP1t3Wz)e$^DNPvdgaxsxE2zWx$hpgK7f!Dla<^^fmYRSe7DUN`f_z!3oN1;@oU# zYzeyP4xa?|s78~<$c=oOl1+Z95h9rkkbl&QBloEi<1p+T)~nLyy<=X)S5h4BoHIak zuKH{07+R63YKA(BqNDYA6zQU^rp6kM{}LZS`5k_Nf**!tbc7o2S0`-`f>V=Ha!{{H zsPy+)aC6_o6`l`ciXwx`B-&wiGZ-xu2CroyR0ptHxJ3U){(=}D1^gw}lzkt|uKe4#_nhmfSDSj(_fzE`A?xN9I`AHmLFi;Yd@2D2% z?1}0<{f5@>PfWm~r%l2tscIt#6xdUbVIe5GcAdf%-0{FoO^%;mwTH(VJ zXcdd0*^YNQJ~ui&*Gkl62)ZqeaZ5dWd#xf~NsR#?A0_ zL1>^Z4JEn?=H_&=X)ttD(DV!5u$vv5m>8npeHY<|MGbhwH(<;+K!H$n(0W&R)ENDe zXXwJKW+w@cs*)%K!?(uqlODo^^3zog_8?bBobUV_`m#!#qA`Eal(^>BZ}OYP`2W;b zX|~O9f7=1u_)H$k{4x`#~f|D^t;E%l@=5w)+D-{pmO`?eDM@@<0bS@5_~tAX6>rGo~) zia(I^gt&7q!+E)bZ+9Ntah3T-cOtyYMJYdZekH>qKea3azQ&n=k7A4xvaT^wG^5@q z=mpN|ht?>tlw#uK65md%ReW0^tWFgXL`eV|shDEqx98sl`6&o86|tEj*GfyjnTEjjt%o;h2}3^U;}-4~ecC zXAe&Lxo24uk{^qWq9IiABV3zJoZ!UzuIx*IZW^``-&dz6HWKK+`_tp4sLGvKHRt#d zS7odWPqXDcxf0Z>_m?Fm?UvB^okzXic!TsX^*U*>es#v9D#v963QP3JbH-w+`Od6Y zgs_-2e5l>!PDr}7z|b+w;Z|W6jo*oyH_*LX>wxbHeBN$kU-lDIi{T=0;3CMPTP&Jm zm{d;7&g2y2q&|-NVktE;xNKGSl8`T??7vY&q5BwW80>ja`M4qnLgfd@dry;^z5aPa zJ8RE;5PM^etX-Z#y`Okfc$lKwco9<%gpNl;41p$ x=&dKvqXhjfUanL?#sB&u4 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 z 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

D5TdiLgKMQG5H+|0kJg^1+ghU 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

!a1lpk`o9}?;>Pvg6H#* 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 RJ%FY>Kut+ou}&Tq^*^nE!ax83 literal 57729 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%0D)^S1AL)Y0xPpNaf96cw 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 Z9q>rSmtMU`%nyKj)Sqc9*D6{^{|{y^_-6nB literal 52424 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 diff --git a/src/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/src/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 23bc2897c3a33f320ce1cf9d9af2c0dde01c3e0b..d7b2e938df56527a079ce956c79cce97e4d7725d 100644 GIT binary patch literal 14095 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�-;3>wg9?U#*qvxG{%^y1)bjU+>mCZo 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

DYUk(_XY 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 Mm{=PVZ@MM?3)>30+5i9m literal 35659 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

bMf<@%^CoV|_xPhiy0iv}V}A$L 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 diff --git a/src/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/src/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 53ed9b9914ba3d1fe703407d2ce64c29e478959c..e358e1ebb7bf666c1fe1b671f15bde6a8106caaa 100644 GIT binary patch literal 62469 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 literal 68697 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 HQ$iB}vIbw5 diff --git a/src/android/app/src/main/res/values/colors.xml b/src/android/app/src/main/res/values/colors.xml index 472567b323..2198022855 100644 --- a/src/android/app/src/main/res/values/colors.xml +++ b/src/android/app/src/main/res/values/colors.xml @@ -1 +1 @@ -#1F143C +#ffd700 From 5575d775200cf1b7811a333e4516c0ff733ba96d Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sun, 10 May 2026 06:38:02 +0200 Subject: [PATCH 26/58] [android] Another set of QoL changes for Android - 2 (#3886) Changes: - Defaults: Set Async GPU and Async Vulkan Presentation to OFF. Stability wasn't worth the trade-off. - Threading: Lowered default pipeline workers from 7 to 4 to reduce heat and CPU contention. - Settings: Added a slider for manual pipeline worker count so users can test what works best for their SoC. - QCOM: Removed SPIRV bans; improves load times and thermals in heavy titles like Jump Force. - UI: Cleaned up settings descriptions to be less ambiguous. ------------------------ Some games fixed: -> Trinity Fusion: No longer crashes with Turnip, no longer shows the black dot in the middle of the screen on both QCOM and Turnip drivers. -> Naruto X Boruto - Ultimate Ninja Storm Connections: Game no longer requires a fixed version of turnip to work (previously requiring Turnip driver from MESA 24.3/ @MrPurple666 EoL v2 driver) Co-authored-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3886 Reviewed-by: crueter Reviewed-by: Lizzie --- .../features/settings/model/IntSetting.kt | 3 ++- .../settings/model/view/SettingsItem.kt | 10 ++++++++++ .../settings/ui/SettingsFragmentPresenter.kt | 1 + .../app/src/main/jni/android_settings.h | 7 +++++++ .../app/src/main/res/values/strings.xml | 12 +++++++----- src/common/settings.h | 6 +++--- .../renderer_vulkan/vk_pipeline_cache.cpp | 19 +++++++++++-------- 7 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt index d1702b8140..60e2a89564 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt @@ -67,7 +67,8 @@ 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"), - GPU_LOG_RING_BUFFER_SIZE("gpu_log_ring_buffer_size") + GPU_LOG_RING_BUFFER_SIZE("gpu_log_ring_buffer_size"), + ANDROID_PIPELINE_WORKERS("pipeline_worker_count") ; override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 3a5f466f07..230390749e 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -582,6 +582,16 @@ abstract class SettingsItem( units = "%" ) ) + put( + SliderSetting( + IntSetting.ANDROID_PIPELINE_WORKERS, + titleId = R.string.pipeline_worker_cores, + descriptionId = R.string.pipeline_worker_cores_description, + min = 4, + max = 8, + units = "cores" + ) + ) put( SingleChoiceSetting( IntSetting.RENDERER_ANTI_ALIASING, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 9f0e409cf4..4da218bfcc 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -295,6 +295,7 @@ class SettingsFragmentPresenter( add(BooleanSetting.EMULATE_BGR565.key) add(BooleanSetting.RESCALE_HACK.key) add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key) + add(IntSetting.ANDROID_PIPELINE_WORKERS.key) add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key) add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key) add(SettingsItem.GPU_UNSWIZZLE_COMBINED) diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h index 37da651519..304ff62f07 100644 --- a/src/android/app/src/main/jni/android_settings.h +++ b/src/android/app/src/main/jni/android_settings.h @@ -147,6 +147,13 @@ namespace AndroidSettings { &show_performance_overlay}; + Settings::Setting pipeline_worker_count{linkage, 4, "pipeline_worker_count", + Settings::Category::Android, + Settings::Specialization::Default, + true, + true}; + + Settings::Setting show_input_overlay{linkage, true, "show_input_overlay", Settings::Category::Overlay}; Settings::Setting overlay_snap_to_grid{linkage, false, "overlay_snap_to_grid", diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 7cdce5339f..7372fa5e34 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -71,6 +71,8 @@ Display current power draw and remaining capacity on battery Show Shaders Building Display current number of shaders being built + Pipeline Worker Threads + Manage the amount of cores used for building Vulkan pipelines, the higher value will improve pipeline compilation performance but temperatures will increase as well. Overlay Position Choose where the overlay is displayed on the screen Top Left @@ -491,15 +493,15 @@ Force maximum clocks (Adreno only) Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied). GPU async emulation - Runs GPU emulation asynchronously to reduce CPU stalls and improve throughput. Disable this only if you run into timing-related issues. + This hack can increase performance by running GPU emulation asynchronously at the cost of graphical issues and increased crash rates by timing-related operations. Asynchronous presentation - Slightly improves performance by moving presentation to a separate CPU thread. + This hack can increase performance by moving presentation to a separate CPU thread at the cost of graphical issues. Use reactive flushing Improves rendering accuracy in some games at the cost of performance. Enable buffer history Enables access to previous buffer states. This option may improve rendering quality and performance consistency in some games. Optimized Vertex Buffers - Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers/ QCOM drivers. Will crash on older Turnip drivers. + Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers/ QCOM drivers. Will crash on older Turnip drivers (25.3 and below). Hacks @@ -531,10 +533,10 @@ Extensions Extended Dynamic State - Controls the number of features that can be used in Extended Dynamic State. Higher numbers allow for more features and can increase performance, but may cause issues with some drivers and vendors. + Controls the number of features that can be used in ExtendedDynamicState (EDS). The higher value will allow to reduce the amount of pipeline compilations based on the dynamic state supported by driver. Disabled Vertex Input Dynamic State - Enables vertex input dynamic state feature for better quality and performance. + Enabling this feature allows for more flexible vertex input handling, potentially reducing pipeline compilation time in vertex/buffer. Sample Shading Allows the fragment shader to execute per sample in a multi-sampled fragment instead once per fragment. Improves graphics quality at the cost of some performance. diff --git a/src/common/settings.h b/src/common/settings.h index d9e1f09dcc..4a6b756ed3 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -389,7 +389,7 @@ struct Values { true}; SwitchableSetting use_asynchronous_gpu_emulation{ - linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer}; + linkage, false, "use_asynchronous_gpu_emulation", Category::Renderer}; // *nix platforms may have issues with the borderless windowed fullscreen mode. // Default to exclusive fullscreen on these platforms for now. SwitchableSetting fullscreen_mode{linkage, @@ -542,7 +542,7 @@ struct Values { true}; SwitchableSetting async_presentation{linkage, #ifdef ANDROID - true, + false, #else false, #endif @@ -609,7 +609,7 @@ struct Values { #if defined (ANDROID) false, #else - true, + false, #endif "vertex_input_dynamic_state", Category::RendererExtensions}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index e365425600..d3a98f1a1c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -45,6 +45,10 @@ #include "video_core/vulkan_common/vulkan_wrapper.h" #include "video_core/gpu_logging/gpu_logging.h" +#ifdef ANDROID +#include "../../android/app/src/main/jni/android_settings.h" +#endif + namespace Vulkan { namespace { @@ -325,13 +329,13 @@ size_t GetTotalPipelineWorkers() { const size_t max_core_threads = std::max(static_cast(std::thread::hardware_concurrency()), 2ULL) - 1ULL; #ifdef ANDROID - // Leave at least one core free on Android. Previously we reserved two, but - // shipping builds benefit from one extra compilation worker. - constexpr size_t free_cores = 1ULL; - if (max_core_threads <= free_cores) { + const int configured = AndroidSettings::values.pipeline_worker_count.GetValue(); + const int clamped = std::clamp(configured, 4, 8); + const size_t desired = static_cast(clamped); + if (desired == 0) { return 1ULL; } - return max_core_threads - free_cores; + return std::min(max_core_threads, desired); #else return max_core_threads; #endif @@ -426,13 +430,12 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA, .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS, - .has_broken_spirv_position_input = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY, + .has_broken_spirv_position_input = driver_id == false, .has_broken_unsigned_image_offsets = false, .has_broken_signed_operations = false, .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY, .ignore_nan_fp_comparisons = false, - .has_broken_spirv_subgroup_mask_vector_extract_dynamic = - driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY, + .has_broken_spirv_subgroup_mask_vector_extract_dynamic = false, .has_broken_robust = device.IsNvidia() && device.GetNvidiaArch() <= NvidiaArchitecture::Arch_Pascal, .min_ssbo_alignment = device.GetStorageBufferAlignment(), From 609756db309f87c349714cd7470f091d1fba0161 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 11 May 2026 18:52:28 +0200 Subject: [PATCH 27/58] [common] Revert default VIDS setting to true to fix AMD GPU and Windows (#3945) Games such as bayonetta 3 or totk need VIDS on for some windows users or it results in broken graphics. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3945 Reviewed-by: crueter Reviewed-by: Lizzie --- src/common/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/settings.h b/src/common/settings.h index 4a6b756ed3..fc347a197e 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -609,7 +609,7 @@ struct Values { #if defined (ANDROID) false, #else - false, + true, #endif "vertex_input_dynamic_state", Category::RendererExtensions}; From 7e84f9ef59314375ff9b626e83c1870173ee14b1 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 11 May 2026 22:03:19 +0200 Subject: [PATCH 28/58] [common] Revert back Aync GPU default to true to fix flickering on Linux (#3946) The cause of the flickering needs to be investigated but this will set it ON as default for desktop platforms. Co-authored-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3946 Reviewed-by: crueter Reviewed-by: Lizzie Reviewed-by: CamilleLaVey --- src/common/settings.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/common/settings.h b/src/common/settings.h index fc347a197e..e10f5105a1 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -388,8 +388,13 @@ struct Values { true, true}; - SwitchableSetting use_asynchronous_gpu_emulation{ - linkage, false, "use_asynchronous_gpu_emulation", Category::Renderer}; + SwitchableSetting use_asynchronous_gpu_emulation{linkage, +#ifdef __ANDROID__ + false, +#else + true, +#endif + "use_asynchronous_gpu_emulation", Category::Renderer}; // *nix platforms may have issues with the borderless windowed fullscreen mode. // Default to exclusive fullscreen on these platforms for now. SwitchableSetting fullscreen_mode{linkage, From b89cd6903c8624107fd7544b568293fc062d677b Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 13 May 2026 19:02:33 +0200 Subject: [PATCH 29/58] [jit] fix Super Mario 64 in SM3D: All-Stars (#3950) jit service had wrong check for module versions missing handlers for some funcs the page cache i added interfered with jit (gee who would've tought) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3950 Reviewed-by: CamilleLaVey Reviewed-by: MaranBr Reviewed-by: crueter --- src/core/arm/dynarmic/arm_dynarmic_32.h | 4 +- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 4 +- src/core/arm/dynarmic/arm_dynarmic_64.h | 4 +- src/core/arm/symbols.cpp | 171 ++++++++++--------- src/core/hle/service/caps/caps_su.cpp | 3 +- src/core/hle/service/jit/jit.cpp | 34 ++-- src/core/hle/service/jit/jit_context.cpp | 191 +++++++++++----------- 7 files changed, 198 insertions(+), 213 deletions(-) diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index d93cc1cfc9..623597152f 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -36,7 +36,7 @@ public: u64 MemoryRead64(u32 vaddr) override; std::optional MemoryReadCode(u32 vaddr) override; void InstructionSynchronizationBarrierRaised() override { - last_code_addr = 0; //reset back, force refetch + last_code_addr = u64(-1); //reset back, force refetch } void MemoryWrite8(u32 vaddr, u8 value) override; void MemoryWrite16(u32 vaddr, u16 value) override; @@ -54,7 +54,7 @@ public: void ReturnException(u32 pc, Dynarmic::HaltReason hr); // Dynarmic::CodePage cached_code_page; - u64 last_code_addr = 0; + u64 last_code_addr = u64(-1); ArmDynarmic32& m_parent; Core::Memory::Memory& m_memory; Kernel::KProcess* m_process{}; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index db8f4424eb..63cc33d9c8 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -45,7 +45,6 @@ Dynarmic::A64::Vector DynarmicCallbacks64::MemoryRead128(u64 vaddr) { std::optional DynarmicCallbacks64::MemoryReadCode(u64 vaddr) { if (!m_memory.IsValidVirtualAddressRange(vaddr, sizeof(u32))) return std::nullopt; -// return m_memory.Read32(vaddr); auto const aligned_vaddr = vaddr & ~Core::Memory::YUZU_PAGEMASK; if (last_code_addr != aligned_vaddr) { m_memory.ReadBlock(aligned_vaddr, &cached_code_page, sizeof(cached_code_page)); @@ -103,6 +102,7 @@ bool DynarmicCallbacks64::MemoryWriteExclusive128(u64 vaddr, Dynarmic::A64::Vect } void DynarmicCallbacks64::InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, u64 value) { + last_code_addr = u64(-1); //invalidate cached page switch (op) { case Dynarmic::A64::InstructionCacheOperation::InvalidateByVAToPoU: { static constexpr u64 ICACHE_LINE_SIZE = 64; @@ -128,7 +128,7 @@ void DynarmicCallbacks64::ExceptionRaised(u64 pc, Dynarmic::A64::Exception excep case Dynarmic::A64::Exception::SendEvent: case Dynarmic::A64::Exception::SendEventLocal: case Dynarmic::A64::Exception::Yield: - LOG_TRACE(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", static_cast(exception), pc, m_memory.Read32(pc)); + LOG_TRACE(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X}, cached = {:08X})", std::size_t(exception), pc, m_memory.Read32(pc), MemoryReadCode(pc).value_or(0)); return; case Dynarmic::A64::Exception::NoExecuteFault: LOG_CRITICAL(Core_ARM, "Cannot execute instruction at unmapped address {:#016x}", pc); diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 9eff17c5fe..6d0760986f 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -43,7 +43,7 @@ public: Dynarmic::A64::Vector MemoryRead128(u64 vaddr) override; std::optional MemoryReadCode(u64 vaddr) override; void InstructionSynchronizationBarrierRaised() override { - last_code_addr = 0; //reset back, force refetch + last_code_addr = u64(-1); //reset back, force refetch } void MemoryWrite8(u64 vaddr, u8 value) override; void MemoryWrite16(u64 vaddr, u16 value) override; @@ -65,7 +65,7 @@ public: void ReturnException(u64 pc, Dynarmic::HaltReason hr); Dynarmic::CodePage cached_code_page; - u64 last_code_addr = 0; + u64 last_code_addr = u64(-1); ArmDynarmic64& m_parent; Core::Memory::Memory& m_memory; u64 m_tpidrro_el0{}; diff --git a/src/core/arm/symbols.cpp b/src/core/arm/symbols.cpp index 0259c7ea27..4e270c319e 100644 --- a/src/core/arm/symbols.cpp +++ b/src/core/arm/symbols.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -13,117 +16,111 @@ using namespace Common::ELF; namespace Core { namespace Symbols { -template -static Symbols GetSymbols(ByteReader ReadBytes) { - const auto Read8{[&](u64 index) { +struct ModuleHeaderLocation { + u32 version; + u32 header_offset; + u32 version_offset; +}; +static_assert(sizeof(ModuleHeaderLocation) == 0x0C); +struct ModuleHeader { + u32 signature; + u32 dynamic_offset; + u32 bss_start_offset; + u32 bss_end_offset; + u32 exception_info_start_offset; + u32 exception_info_end_offset; + u32 module_offset; + u32 relro_start_offset; + u32 full_relro_end_offset; + u32 nx_debug_link_start_offset; + u32 nx_debug_link_end_offset; + u32 note_gnu_build_id_start_offset; + u32 note_gnu_build_id_end_offset; +}; +static_assert(sizeof(ModuleHeader) == 0x34); + +struct Mod32 { + using Sym = Elf32_Sym; + using Dyn = Elf32_Dyn; +}; +struct Mod64 { + using Sym = Elf64_Sym; + using Dyn = Elf64_Dyn; +}; + +template +static Symbols GetSymbols(F&& ReadBytes) { + const auto Read8 = [&](u64 index) { u8 ret; ReadBytes(&ret, index, sizeof(u8)); return ret; - }}; - - const auto Read32{[&](u64 index) { - u32 ret; - ReadBytes(&ret, index, sizeof(u32)); - return ret; - }}; - - const auto ReadWord{[&](u64 index) { - Word ret; - ReadBytes(&ret, index, sizeof(Word)); - return ret; - }}; - - const u32 mod_offset = Read32(4); - - if (Read32(mod_offset) != Common::MakeMagic('M', 'O', 'D', '0')) { + }; + ModuleHeaderLocation loc{}; + ReadBytes(&loc, 0, sizeof(ModuleHeaderLocation)); + ModuleHeader hdr; + ReadBytes(&hdr, loc.header_offset, sizeof(ModuleHeader)); + if (hdr.signature != Common::MakeMagic('M', 'O', 'D', '0')) { return {}; } - VAddr string_table_offset{}; - VAddr symbol_table_offset{}; - u64 symbol_entry_size{}; - - const auto dynamic_offset = Read32(mod_offset + 0x4) + mod_offset; - - VAddr dynamic_index = dynamic_offset; + VAddr strtab_offs{}; + VAddr symtab_offs{}; + u64 syment_size = sizeof(typename M::Sym); + VAddr dynamic_offset = loc.header_offset + hdr.dynamic_offset; while (true) { - const Word tag = ReadWord(dynamic_index); - const Word value = ReadWord(dynamic_index + sizeof(Word)); - dynamic_index += 2 * sizeof(Word); - - if (tag == ElfDtNull) { + typename M::Dyn dyn; + ReadBytes(&dyn, dynamic_offset, sizeof(typename M::Dyn)); + dynamic_offset += sizeof(typename M::Dyn); + if (dyn.d_tag == ElfDtNull) { break; } - - if (tag == ElfDtStrtab) { - string_table_offset = value; - } else if (tag == ElfDtSymtab) { - symbol_table_offset = value; - } else if (tag == ElfDtSyment) { - symbol_entry_size = value; + if (dyn.d_tag == ElfDtStrtab) { + strtab_offs = dyn.d_un.d_ptr; + } else if (dyn.d_tag == ElfDtSymtab) { + symtab_offs = dyn.d_un.d_ptr; + } else if (dyn.d_tag == ElfDtSyment) { + syment_size = dyn.d_un.d_val; } } - - if (string_table_offset == 0 || symbol_table_offset == 0 || symbol_entry_size == 0) { - return {}; - } - - Symbols out; - - VAddr symbol_index = symbol_table_offset; - while (symbol_index < string_table_offset) { - ELFSymbol symbol{}; - ReadBytes(&symbol, symbol_index, sizeof(ELFSymbol)); - - VAddr string_offset = string_table_offset + symbol.st_name; - std::string name; - for (u8 c = Read8(string_offset); c != 0; c = Read8(++string_offset)) { - name += static_cast(c); + if (strtab_offs > 0 && symtab_offs > 0) { + Symbols out; + VAddr symbol_index = symtab_offs; + while (symbol_index < strtab_offs) { + typename M::Sym symbol{}; + ReadBytes(&symbol, symbol_index, sizeof(typename M::Sym)); + VAddr offs = strtab_offs + symbol.st_name; + std::string name{}; + for (u8 c = Read8(offs); c != 0; c = Read8(++offs)) + name += char(c); + symbol_index += syment_size; + out[name] = std::make_pair(symbol.st_value, symbol.st_size); } - - symbol_index += symbol_entry_size; - out[name] = std::make_pair(symbol.st_value, symbol.st_size); + return out; } - - return out; + return {}; } Symbols GetSymbols(VAddr base, Core::Memory::Memory& memory, bool is_64) { - const auto ReadBytes{ - [&](void* ptr, size_t offset, size_t size) { memory.ReadBlock(base + offset, ptr, size); }}; - - if (is_64) { - return GetSymbols(ReadBytes); - } else { - return GetSymbols(ReadBytes); - } + const auto f = [base, &memory](void* ptr, size_t offset, size_t size) { + memory.ReadBlock(base + offset, ptr, size); + }; + return is_64 ? GetSymbols(f) : GetSymbols(f); } Symbols GetSymbols(std::span data, bool is_64) { - const auto ReadBytes{[&](void* ptr, size_t offset, size_t size) { + const auto f = [data](void* ptr, size_t offset, size_t size) { std::memcpy(ptr, data.data() + offset, size); - }}; - - if (is_64) { - return GetSymbols(ReadBytes); - } else { - return GetSymbols(ReadBytes); - } + }; + return is_64 ? GetSymbols(f) : GetSymbols(f); } std::optional GetSymbolName(const Symbols& symbols, VAddr addr) { - const auto iter = std::find_if(symbols.cbegin(), symbols.cend(), [addr](const auto& pair) { - const auto& [name, sym_info] = pair; - const auto& [start_address, size] = sym_info; - const auto end_address = start_address + size; - return addr >= start_address && addr < end_address; + const auto it = std::find_if(symbols.cbegin(), symbols.cend(), [addr](const auto& e) { + auto const [start, size] = e.second; + auto const end = start + size; + return addr >= start && addr < end; }); - - if (iter == symbols.cend()) { - return std::nullopt; - } - - return iter->first; + return it != symbols.cend() ? std::optional{it->first} : std::nullopt; } } // namespace Symbols diff --git a/src/core/hle/service/caps/caps_su.cpp b/src/core/hle/service/caps/caps_su.cpp index 8622ab058f..d89f147a75 100644 --- a/src/core/hle/service/caps/caps_su.cpp +++ b/src/core/hle/service/caps/caps_su.cpp @@ -33,8 +33,7 @@ IScreenShotApplicationService::IScreenShotApplicationService( IScreenShotApplicationService::~IScreenShotApplicationService() = default; -Result IScreenShotApplicationService::SetShimLibraryVersion(ShimLibraryVersion library_version, - ClientAppletResourceUserId aruid) { +Result IScreenShotApplicationService::SetShimLibraryVersion(ShimLibraryVersion library_version, ClientAppletResourceUserId aruid) { LOG_WARNING(Service_Capture, "(STUBBED) called. library_version={}, applet_resource_user_id={}", library_version, aruid.pid); R_SUCCEED(); diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp index 4941a71a01..1179e8b61d 100644 --- a/src/core/hle/service/jit/jit.cpp +++ b/src/core/hle/service/jit/jit.cpp @@ -1,6 +1,10 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/logging.h" #include "core/arm/debug.h" #include "core/arm/symbols.h" #include "core/core.h" @@ -111,10 +115,7 @@ public: const VAddr input_ptr{context.AddHeap(in_data.data(), in_data.size())}; const VAddr output_ptr{context.AddHeap(out_data.data(), out_data.size())}; - const u64 wrapper_value{context.CallFunction(callbacks.Control, ret_ptr, configuration_ptr, - command, input_ptr, in_data.size(), output_ptr, - out_data.size())}; - + const u64 wrapper_value = context.CallFunction(callbacks.Control, ret_ptr, configuration_ptr, command, input_ptr, in_data.size(), output_ptr, out_data.size()); *out_return_value = context.GetHeap(ret_ptr); context.GetHeap(output_ptr, out_data.data(), out_data.size()); @@ -126,9 +127,7 @@ public: R_THROW(ResultUnknown); } - Result LoadPlugin(u64 tmem_size, InCopyHandle tmem, - InBuffer nrr, - InBuffer nro) { + Result LoadPlugin(u64 tmem_size, InCopyHandle tmem, InBuffer nrr, InBuffer nro) { if (!tmem) { LOG_ERROR(Service_JIT, "Invalid transfer memory handle!"); R_THROW(ResultUnknown); @@ -139,9 +138,10 @@ public: configuration.transfer_memory.size = tmem_size; // Gather up all the callbacks from the loaded plugin - auto symbols{Core::Symbols::GetSymbols(nro, true)}; - const auto GetSymbol{[&](const std::string& name) { return symbols[name].first; }}; - + auto symbols = Core::Symbols::GetSymbols(nro, true); + const auto GetSymbol = [&](const std::string& name) { + return symbols[name].first; + }; callbacks.rtld_fini = GetSymbol("_fini"); callbacks.rtld_init = GetSymbol("_init"); callbacks.Control = GetSymbol("nnjitpluginControl"); @@ -153,8 +153,7 @@ public: callbacks.OnPrepared = GetSymbol("nnjitpluginOnPrepared"); callbacks.Keeper = GetSymbol("nnjitpluginKeeper"); - if (callbacks.GetVersion == 0 || callbacks.Configure == 0 || callbacks.GenerateCode == 0 || - callbacks.OnPrepared == 0) { + if (callbacks.GetVersion == 0 || callbacks.Configure == 0 || callbacks.GenerateCode == 0 || callbacks.OnPrepared == 0 || callbacks.Control == 0) { LOG_ERROR(Service_JIT, "plugin does not implement all necessary functionality"); R_THROW(ResultUnknown); } @@ -164,12 +163,9 @@ public: R_THROW(ResultUnknown); } - context.MapProcessMemory(configuration.sys_ro_memory.offset, - configuration.sys_ro_memory.size); - context.MapProcessMemory(configuration.sys_rx_memory.offset, - configuration.sys_rx_memory.size); - context.MapProcessMemory(configuration.transfer_memory.offset, - configuration.transfer_memory.size); + context.MapProcessMemory(configuration.sys_ro_memory.offset, configuration.sys_ro_memory.size); + context.MapProcessMemory(configuration.sys_rx_memory.offset, configuration.sys_rx_memory.size); + context.MapProcessMemory(configuration.transfer_memory.offset, configuration.transfer_memory.size); // Run ELF constructors, if needed if (callbacks.rtld_init != 0) { @@ -179,7 +175,7 @@ public: // Function prototype: // u64 GetVersion(); const auto version{context.CallFunction(callbacks.GetVersion)}; - if (version != 1) { + if (version > 1) { LOG_ERROR(Service_JIT, "unknown plugin version {}", version); R_THROW(ResultUnknown); } diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp index 522d849e6f..ce51fbd3f5 100644 --- a/src/core/hle/service/jit/jit_context.cpp +++ b/src/core/hle/service/jit/jit_context.cpp @@ -24,15 +24,25 @@ using namespace Common::ELF; namespace Service::JIT { +enum HelperFn { + None, + Stop, + Resolve, + Panic, + Memcpy, + Memmove, + Memset, + // sm64 + PanicForPlugin, + AbortImpl, + UnexpectedImpl, + Count +}; + constexpr std::array SVC0_ARM64 = { 0x01, 0x00, 0x00, 0xd4, // svc #0 0xc0, 0x03, 0x5f, 0xd6, // ret }; - -constexpr std::array HELPER_FUNCTIONS{ - "_stop", "_resolve", "_panic", "memcpy", "memmove", "memset", -}; - constexpr size_t STACK_ALIGN = 16; class JITContextImpl; @@ -42,10 +52,12 @@ using IntervalType = boost::icl::interval_set::interval_type; class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { public: - explicit DynarmicCallbacks64(Core::Memory::Memory& memory_, std::vector& local_memory_, - IntervalSet& mapped_ranges_, JITContextImpl& parent_) - : memory{memory_}, local_memory{local_memory_}, - mapped_ranges{mapped_ranges_}, parent{parent_} {} + explicit DynarmicCallbacks64(Core::Memory::Memory& memory_, std::vector& local_memory_, IntervalSet& mapped_ranges_, JITContextImpl& parent_) + : memory{memory_} + , local_memory{local_memory_} + , mapped_ranges{mapped_ranges_} + , parent{parent_} + {} std::optional MemoryReadCode(VAddr vaddr) override { static_assert(Core::Memory::YUZU_PAGESIZE == Dynarmic::CODE_PAGE_SIZE); @@ -57,7 +69,7 @@ public: return cached_code_page.inst[(vaddr & Core::Memory::YUZU_PAGEMASK) / sizeof(u32)]; } void InstructionSynchronizationBarrierRaised() override { - last_code_addr = 0; //reset back, force refetch + last_code_addr = u64(-1); //reset back, force refetch } u8 MemoryRead8(u64 vaddr) override { return ReadMemory(vaddr); @@ -75,13 +87,10 @@ public: return ReadMemory(vaddr); } std::string MemoryReadCString(u64 vaddr) { - std::string result; + std::string result{}; u8 next; - - while ((next = MemoryRead8(vaddr++)) != 0) { - result += next; - } - + while ((next = MemoryRead8(vaddr++)) != 0) + result += char(next); return result; } @@ -157,32 +166,26 @@ private: std::vector& local_memory; IntervalSet& mapped_ranges; JITContextImpl& parent; - Dynarmic::CodePage cached_code_page; - u64 last_code_addr = 0; + u64 last_code_addr = u64(-1); }; class JITContextImpl { public: explicit JITContextImpl(Core::Memory::Memory& memory_) : memory{memory_} { - callbacks = - std::make_unique(memory, local_memory, mapped_ranges, *this); - user_config.callbacks = callbacks.get(); - jit = std::make_unique(user_config); + callbacks.emplace(memory, local_memory, mapped_ranges, *this); + user_config.callbacks = std::addressof(callbacks.value()); + jit.emplace(user_config); } bool LoadNRO(std::span data) { - local_memory.clear(); - relocbase = local_memory.size(); local_memory.insert(local_memory.end(), data.begin(), data.end()); - if (FixupRelocations()) { InsertHelperFunctions(); InsertStack(); return true; } - return false; } @@ -190,11 +193,9 @@ public: // The loaded NRO file has ELF relocations that must be processed before it can run. // Normally this would be processed by RTLD, but in HLE context, we don't have // the linker available, so we have to do it ourselves. - const VAddr mod_offset{callbacks->MemoryRead32(4)}; - if (callbacks->MemoryRead32(mod_offset) != Common::MakeMagic('M', 'O', 'D', '0')) { + if (callbacks->MemoryRead32(mod_offset) != Common::MakeMagic('M', 'O', 'D', '0')) return false; - } // For more info about dynamic entries, see the ELF ABI specification: // https://refspecs.linuxbase.org/elf/gabi4+/ch5.dynamic.html @@ -205,40 +206,33 @@ public: while (true) { const auto dyn{callbacks->ReadMemory(dynamic_offset)}; dynamic_offset += sizeof(Elf64_Dyn); - if (!dyn.d_tag) { break; - } - if (dyn.d_tag == ElfDtRela) { + } else if (dyn.d_tag == ElfDtRela) { rela_dyn = dyn.d_un.d_ptr; - } - if (dyn.d_tag == ElfDtRelasz) { + } else if (dyn.d_tag == ElfDtRelasz) { num_rela = dyn.d_un.d_val / sizeof(Elf64_Rela); - } - if (dyn.d_tag == ElfDtRelr) { + } else if (dyn.d_tag == ElfDtRelr) { relr_dyn = dyn.d_un.d_ptr; - } - if (dyn.d_tag == ElfDtRelrsz) { + } else if (dyn.d_tag == ElfDtRelrsz) { num_relr = dyn.d_un.d_val / sizeof(Elf64_Relr); } } for (size_t i = 0; i < num_rela; i++) { const auto rela{callbacks->ReadMemory(rela_dyn + i * sizeof(Elf64_Rela))}; - if (Elf64RelType(rela.r_info) != ElfAArch64Relative) { - continue; + if (Elf64RelType(rela.r_info) == ElfAArch64Relative) { + const VAddr contents{callbacks->MemoryRead64(rela.r_offset)}; + callbacks->MemoryWrite64(rela.r_offset, contents + rela.r_addend); } - const VAddr contents{callbacks->MemoryRead64(rela.r_offset)}; - callbacks->MemoryWrite64(rela.r_offset, contents + rela.r_addend); } VAddr relr_where = 0; for (size_t i = 0; i < num_relr; i++) { - const auto relr{callbacks->ReadMemory(relr_dyn + i * sizeof(Elf64_Relr))}; - const auto incr{[&](VAddr where) { + const auto relr = callbacks->ReadMemory(relr_dyn + i * sizeof(Elf64_Relr)); + const auto incr = [&](VAddr where) { callbacks->MemoryWrite64(where, callbacks->MemoryRead64(where) + relocbase); - }}; - + }; if ((relr & 1) == 0) { // where pointer relr_where = relocbase + relr; @@ -254,13 +248,12 @@ public: relr_where += 63 * sizeof(Elf64_Addr); } } - return true; } void InsertHelperFunctions() { - for (const auto& name : HELPER_FUNCTIONS) { - helpers[name] = local_memory.size(); + for (size_t i = 0; i < size_t(HelperFn::Count); ++i) { + helpers[i] = local_memory.size(); local_memory.insert(local_memory.end(), SVC0_ARM64.begin(), SVC0_ARM64.end()); } } @@ -268,9 +261,8 @@ public: void InsertStack() { // Allocate enough space to avoid any reasonable risk of // overflowing the stack during plugin execution - const u64 pad_amount{Common::AlignUp(local_memory.size(), STACK_ALIGN) - - local_memory.size()}; - local_memory.insert(local_memory.end(), 0x10000 + pad_amount, 0); + const u64 pad_amount = Common::AlignUp(local_memory.size(), STACK_ALIGN) - local_memory.size(); + local_memory.insert(local_memory.end(), (4096 * 32) + pad_amount, 0); top_of_stack = local_memory.size(); heap_pointer = top_of_stack; } @@ -297,27 +289,21 @@ public: // // For more info, see the AArch64 ABI PCS: // https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst - - for (size_t i = 0; i < 8 && i < argument_stack.size(); i++) { + for (size_t i = 0; i < 8 && i < argument_stack.size(); i++) jit->SetRegister(i, argument_stack[i]); - } - if (argument_stack.size() > 8) { - const VAddr new_sp = Common::AlignDown( - top_of_stack - (argument_stack.size() - 8) * sizeof(u64), STACK_ALIGN); - for (size_t i = 8; i < argument_stack.size(); i++) { + const VAddr new_sp = Common::AlignDown(top_of_stack - (argument_stack.size() - 8) * sizeof(u64), STACK_ALIGN); + for (size_t i = 8; i < argument_stack.size(); i++) callbacks->MemoryWrite64(new_sp + (i - 8) * sizeof(u64), argument_stack[i]); - } jit->SetSP(new_sp); } - // Reset the call state for the next invocation argument_stack.clear(); heap_pointer = top_of_stack; } u64 CallFunction(VAddr func) { - jit->SetRegister(30, helpers["_stop"]); + jit->SetRegister(30, helpers[size_t(HelperFn::Stop)]); jit->SetSP(top_of_stack); SetupArguments(); @@ -326,21 +312,14 @@ public: return jit->GetRegister(0); } - VAddr GetHelper(const std::string& name) { - return helpers[name]; - } - VAddr AddHeap(const void* data, size_t size) { // Require all heap data types to have the same alignment as the // stack pointer, for compatibility - const size_t num_bytes{Common::AlignUp(size, STACK_ALIGN)}; - + const size_t num_bytes = Common::AlignUp(size, STACK_ALIGN); // Make additional memory space if required if (heap_pointer + num_bytes > local_memory.size()) { - local_memory.insert(local_memory.end(), - (heap_pointer + num_bytes) - local_memory.size(), 0); + local_memory.insert(local_memory.end(), (heap_pointer + num_bytes) - local_memory.size(), 0); } - const VAddr location{heap_pointer}; std::memcpy(local_memory.data() + location, data, size); heap_pointer += num_bytes; @@ -351,13 +330,29 @@ public: std::memcpy(data, local_memory.data() + location, size); } - std::unique_ptr callbacks; + VAddr GetHelper(const std::string& name) { + if (name == "_resolve") return helpers[HelperFn::Resolve]; + else if (name == "_panic") return helpers[HelperFn::Panic]; + else if (name == "_stop") return helpers[HelperFn::Stop]; + else if (name == "memset") return helpers[HelperFn::Memset]; + else if (name == "memcpy") return helpers[HelperFn::Memcpy]; + else if (name == "memmove") return helpers[HelperFn::Memmove]; + else if (name == "PanicForPlugin") return helpers[HelperFn::PanicForPlugin]; + else if (name == "_ZN2nn4diag6detail9AbortImplEPKcS3_S3_i") return helpers[HelperFn::AbortImpl]; + else if (name == "_ZN2nn6detail21UnexpectedDefaultImplEPKcS2_i") return helpers[HelperFn::UnexpectedImpl]; + else { + LOG_CRITICAL(Service_JIT, "unresolved {}", name); + return helpers[HelperFn::Panic]; + } + } + + std::optional callbacks; + std::optional jit; std::vector local_memory; - std::vector argument_stack; + std::vector argument_stack; IntervalSet mapped_ranges; Dynarmic::A64::UserConfig user_config; - std::unique_ptr jit; - std::map> helpers; + std::array helpers; Core::Memory::Memory& memory; VAddr top_of_stack; VAddr heap_pointer; @@ -383,44 +378,41 @@ void DynarmicCallbacks64::CallSVC(u32 swi) { } u64 pc{parent.jit->GetPC() - 4}; - auto& helpers{parent.helpers}; - - if (pc == helpers["memcpy"] || pc == helpers["memmove"]) { + if (pc == parent.helpers[size_t(HelperFn::Memcpy)] || pc == parent.helpers[size_t(HelperFn::Memmove)]) { const VAddr dest{parent.jit->GetRegister(0)}; const VAddr src{parent.jit->GetRegister(1)}; const size_t n{parent.jit->GetRegister(2)}; if (dest < src) { - for (size_t i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) MemoryWrite8(dest + i, MemoryRead8(src + i)); - } } else { - for (size_t i = n; i > 0; i--) { + for (size_t i = n; i > 0; i--) MemoryWrite8(dest + i - 1, MemoryRead8(src + i - 1)); - } } - } else if (pc == helpers["memset"]) { + } else if (pc == parent.helpers[size_t(HelperFn::Memset)]) { const VAddr dest{parent.jit->GetRegister(0)}; const u64 c{parent.jit->GetRegister(1)}; const size_t n{parent.jit->GetRegister(2)}; - - for (size_t i = 0; i < n; i++) { - MemoryWrite8(dest + i, static_cast(c)); - } - } else if (pc == helpers["_resolve"]) { + for (size_t i = 0; i < n; i++) + MemoryWrite8(dest + i, u8(c)); + } else if (pc == parent.helpers[size_t(HelperFn::Resolve)]) { // X0 contains a char* for a symbol to resolve const auto name{MemoryReadCString(parent.jit->GetRegister(0))}; - const auto helper{helpers[name]}; - - if (helper != 0) { - parent.jit->SetRegister(0, helper); - } else { - LOG_WARNING(Service_JIT, "plugin requested unknown function {}", name); - parent.jit->SetRegister(0, helpers["_panic"]); - } - } else if (pc == helpers["_stop"]) { + parent.jit->SetRegister(0, u64(parent.GetHelper(name))); + } else if (pc == parent.helpers[size_t(HelperFn::Stop)]) { parent.jit->HaltExecution(); - } else if (pc == helpers["_panic"]) { + } else if (pc == parent.helpers[size_t(HelperFn::Panic)]) { + LOG_CRITICAL(Service_JIT, "plugin panicked!"); + parent.jit->HaltExecution(); + // SM64 + } else if (pc == parent.helpers[size_t(HelperFn::PanicForPlugin)]) { + LOG_CRITICAL(Service_JIT, "plugin panicked!"); + parent.jit->HaltExecution(); + } else if (pc == parent.helpers[size_t(HelperFn::AbortImpl)]) { + LOG_CRITICAL(Service_JIT, "plugin panicked!"); + parent.jit->HaltExecution(); + } else if (pc == parent.helpers[size_t(HelperFn::UnexpectedImpl)]) { LOG_CRITICAL(Service_JIT, "plugin panicked!"); parent.jit->HaltExecution(); } else { @@ -430,7 +422,8 @@ void DynarmicCallbacks64::CallSVC(u32 swi) { } void DynarmicCallbacks64::ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) { - LOG_CRITICAL(Service_JIT, "Illegal operation PC @ {:08x}", pc); + auto const inst = MemoryRead32(pc); + LOG_CRITICAL(Service_JIT, "{} PC @ {:08x}, data = {:08x}", exception, pc, inst); parent.jit->HaltExecution(); } From d8070c74c3bc8817ec619c8d99166e0112512c78 Mon Sep 17 00:00:00 2001 From: Eden CI Date: Wed, 13 May 2026 19:13:16 +0200 Subject: [PATCH 30/58] [dist, android] Update translations from Transifex for May 12 (#3949) Automatic translation update for May 12 Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3949 --- dist/languages/pt_BR.ts | 174 ++++++++++-------- .../app/src/main/res/values-ar/strings.xml | 14 +- .../app/src/main/res/values-cs/strings.xml | 2 - .../app/src/main/res/values-de/strings.xml | 2 - .../app/src/main/res/values-es/strings.xml | 11 +- .../app/src/main/res/values-fr/strings.xml | 1 - .../app/src/main/res/values-pl/strings.xml | 2 - .../src/main/res/values-pt-rBR/strings.xml | 1 - .../app/src/main/res/values-ru/strings.xml | 18 +- .../app/src/main/res/values-uk/strings.xml | 14 +- .../src/main/res/values-zh-rCN/strings.xml | 6 - .../src/main/res/values-zh-rTW/strings.xml | 1 - 12 files changed, 131 insertions(+), 115 deletions(-) diff --git a/dist/languages/pt_BR.ts b/dist/languages/pt_BR.ts index aa64808086..1bb88abafc 100644 --- a/dist/languages/pt_BR.ts +++ b/dist/languages/pt_BR.ts @@ -119,12 +119,12 @@ li.checked::marker { content: "\2612"; } %1 has been banned - %1 foi banido(a) + %1 foi banido %1 has been unbanned - %1 foi desbanido(a) + %1 foi desbanido @@ -782,13 +782,14 @@ Desabiltar essa opção só serve para propósitos de depuração. Use asynchronous GPU emulation - + Usar emulação assíncrona de GPU Uses an extra CPU thread for rendering. This option should always remain enabled. - + Usa uma thread de CPU extra para renderização. +Esta opção deve estar sempre habilitada. @@ -2801,32 +2802,32 @@ Quando um programa tenta abrir o applet, ele é imediatamente fechado. Bitmask for quick development toggles - + Bitmask para rápida alternativa de desenvolvimento Set debug knobs (bitmask) - + Definir knobs de depuração (bitmask) 16-bit debug knob set for quick development toggles - + Knob de depuração 16-bit definido para rápida alternativa de desenvolvimento (bitmask) - + (bitmask) Debug Knobs: - + Knobs de depuração: Unit Serial: - + Número de série: @@ -2841,7 +2842,7 @@ Quando um programa tenta abrir o applet, ele é imediatamente fechado. Flush log output on each line - + Liberar o log a cada linha @@ -2856,7 +2857,7 @@ Quando um programa tenta abrir o applet, ele é imediatamente fechado. Censor username in logs - + Censurar nome de usuário nos logs @@ -2960,7 +2961,7 @@ Quando um programa tenta abrir o applet, ele é imediatamente fechado. GraphicsExtra - + Gráficos Extra @@ -3040,7 +3041,7 @@ Quando um programa tenta abrir o applet, ele é imediatamente fechado. Save Data - + Salvar dados @@ -3116,7 +3117,7 @@ Quando um programa tenta abrir o applet, ele é imediatamente fechado. Select Save Data Directory... - + Selecionar o diretório de salvamento @@ -3136,22 +3137,22 @@ Quando um programa tenta abrir o applet, ele é imediatamente fechado. Save Data Directory - + Salvar diretório de salvamento Choose an action for the save data directory: - + Escolha uma ação para o diretório de salvamento: Set Custom Path - + Definir caminho personalizado Reset to NAND - + Resetar a NAND @@ -3162,7 +3163,13 @@ New: %2 Would you like to migrate saves from the old location? WARNING: This will overwrite any conflicting saves in the new location! - + Salvamento existe tanto no antigo quanto nas novas locações. + +Antigo: %1 +Novo: %2 + +Você gostaria de migrar seu salvamento do antigo local? +ATENÇÃO: Isso irá sobrescrever qualquer salvamento conflitante no novo local! @@ -3170,51 +3177,57 @@ WARNING: This will overwrite any conflicting saves in the new location! From: %1 To: %2 - + Você gostaria de migrar seus salvamentos para o novo local? + +De: %1 +Para: %2 Migrate Save Data - + Migrar salvamento Migrating save data... - + Migrando salvamento... Cancel - + Cancelar Migration Failed - + Migração Falhou Failed to create destination directory. - + Falha ao criar diretório de destino. Failed to migrate save data: %1 - + Falha ao migrar salvamento: +1% Migration Complete - + Migração Completa Save data has been migrated successfully. Would you like to delete the old save data? - + Salvamento foi migrado com sucesso + +Gostaria de deletar o salvamento antigo? @@ -3363,27 +3376,27 @@ Would you like to delete the old save data? Form - + Formar Extras - + Extras Hacks - + Hacks Changing these options from their default may cause issues. Novitii cavete! - + Alterar essas opções de seus padrões pode causar problemas. È una trappola, Bino! Vulkan Extensions - + Extensões Vulkan @@ -3394,7 +3407,7 @@ Would you like to delete the old save data? Extended Dynamic State is disabled on macOS due to MoltenVK compatibility issues that cause black screens. - + Estado Dinâmico Extendido é desativado no MacOS, devido a problemas de compatibilidade com o MoltenVK, que causa telas pretas. @@ -4709,7 +4722,7 @@ Os valores atuais são %1% e %2% respectivamente. Enable Airplane Mode - + Habilitar Modo Avião @@ -4792,7 +4805,7 @@ Os valores atuais são %1% e %2% respectivamente. Ext. Graphics - + Gráficos Ext. @@ -4807,7 +4820,7 @@ Os valores atuais são %1% e %2% respectivamente. Network - + Rede @@ -4835,12 +4848,12 @@ Os valores atuais são %1% e %2% respectivamente. Import Mod from ZIP - + Importar Mod a partir de ZIP Import Mod from Folder - + Importar Mod a partir da Pasta @@ -4855,87 +4868,92 @@ Os valores atuais são %1% e %2% respectivamente. Mod Install Succeeded - + Instalação de Mod Concluída Successfully installed all mods. - + Todos os Mods foram instalados com sucesso. Mod Install Failed - + Instalação de Mod Falhou Failed to install the following mods: %1 Check the log for details. - + Falha ao instalar os seguintes Mods: + %1 +Cheque o log para mais detalhes. Mod Folder - + Pasta de Mods Zipped Mod Location - + Local de Mod Empacotado Zipped Archives (*.zip) - + Arquivos Empacotados (*.zip) Invalid Selection - + Seleção inválida Only mods, cheats, and patches can be deleted. To delete NAND-installed updates, right-click the game in the game list and click Remove -> Remove Installed Update. - + Apenas Mods, trapaças e correções podem ser deletadas. +Para deletar atualizações instaladas na NAND, pressione o botão direito no jogo na lista e clique em Remover -> Remova Atualização Instalada. You are about to delete the following installed mods: - + Você está a prestes de deletar os seguintes Mods instalados: + Once deleted, these can NOT be recovered. Are you 100% sure you want to delete them? - + +Uma vez deletado, esses NÃO podem ser recuperados. Você tem 100% de certeza que quer deletar eles? Delete add-on(s)? - + Deletar add-on(s)? Successfully deleted - + Deletado com sucesso Successfully deleted all selected mods. - + Todos os Mods selecionados foram deletados com sucesso. &Delete - + &Deletar &Open in File Manager - + &Abrir Gerenciador de Arquivos @@ -5021,27 +5039,27 @@ Once deleted, these can NOT be recovered. Are you 100% sure you want to delete t Error saving user image - + Erro ao salvar imagem de usuário Unable to save image to file - + Incapaz de salvar imagem para arquivo &Edit - + &Editar &Delete - + &Deletar Edit User - + Editar Usuário @@ -5226,7 +5244,7 @@ UUID: %2 <html><head/><body><p>Reads controller input from scripts in the same format as TAS-nx scripts.<br/>For a more detailed explanation, please consult the user handbook.</p></body></html> - + <html><head/><body><p>Lê as entradas do controle a partir de scripts no mesmo formato que o TAS-nx.<br/>Para uma explicação mais detalhada, por favor consulte o manual do usuário.</p></body></html> @@ -5261,7 +5279,7 @@ UUID: %2 Show recording dialog - + Mostrar gravações de diálogo @@ -5394,7 +5412,7 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta Warning: The settings in this page affect the inner workings of Eden's emulated touchscreen. Changing them may result in undesirable behavior, such as the touchscreen partially or not working. You should only use this page if you know what you are doing. - + Atenção: As configurações desta página podem mudar o funcionamento interno do touchscreen emulado do Eden. Mudar elas pode causar problemas indesejados, como o touchscreen parando de funcionar parcialmente e até mesmo por completo. Você deverá apenas usar essa página se você sabe o que está fazendo. @@ -5690,7 +5708,7 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta Eden Web Service - + Serviço Web do Eden @@ -5705,7 +5723,7 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta Generate - + Gerar @@ -5727,19 +5745,19 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta All Good Tooltip - + Tudo certo Must be between 4-20 characters Tooltip - + Deve conter entre 4-20 caracteres Must be 48 characters, and lowercase a-z Tooltip - + Deve ser em 48 caracteres, e letras minúsculas de a-z @@ -5760,12 +5778,12 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta Data Manager - + Gestor de Dados Deleting ANY data is IRREVERSABLE! - + Deletar QUAISQUER dados é IRREVERSÍVEL! @@ -5775,12 +5793,12 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta User NAND - + NAND de Usuário System NAND - + NAND do Sistema @@ -5790,7 +5808,7 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta Saves - + Salvamentos @@ -5798,17 +5816,17 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta Form - + Formar Tooltip - + Dica de Ferramenta Open with your system file manager - + Abrir gerenciador de arquivos do sistema @@ -6063,7 +6081,7 @@ Please go to Configure -> System -> Network and make a selection. Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.<br><br>GL Renderer:<br>%1 - O teu GPU pode não suportar OpenGL 4.6, ou não tem os drivers gráficos mais recentes. + A sua GPU não tem suporte a OpenGL 4.6, talvez você não esteja usando os drivers gráficos mais atuais.<br><br>Renderizador GL:<br>%1 diff --git a/src/android/app/src/main/res/values-ar/strings.xml b/src/android/app/src/main/res/values-ar/strings.xml index 3fc4c0c139..08d56dea49 100644 --- a/src/android/app/src/main/res/values-ar/strings.xml +++ b/src/android/app/src/main/res/values-ar/strings.xml @@ -66,6 +66,8 @@ عرض استهلاك الطاقة الحالي والسعة المتبقية في البطارية عرض بناء التظليل عرض عدد التظليل التي يتم بناؤها + خيوط عامل خط الأنابيب + قم بإدارة عدد النوى المستخدمة لبناء خطوط أنابيب Vulkan، فالقيمة الأعلى ستحسن أداء تجميع خط الأنابيب ولكن درجات الحرارة سترتفع أيضًا. موضع الطبقة حدد مكان عرض الطبقة على الشاشة أعلى اليمين @@ -485,15 +487,15 @@ إجبار السرعة القصوى (لأجهزة Adreno فقط) يجبر وحدة معالجة الرسومات على العمل بأقصى سرعة ممكنة (سيظل يتم تطبيق القيود الحرارية). محاكاة غير متزامنة لوحدة معالجة الرسومات - يُشغّل هذا الخيار محاكاة وحدة معالجة الرسومات بشكل غير متزامن لتقليل توقف وحدة المعالجة المركزية وتحسين الإنتاجية. عطّل هذا الخيار فقط في حال واجهت مشاكل متعلقة بالتوقيت. + يمكن لهذه الحيلة أن تزيد الأداء عن طريق تشغيل محاكاة وحدة معالجة الرسومات بشكل غير متزامن على حساب مشاكل الرسومات وزيادة معدلات الأعطال بسبب العمليات المتعلقة بالتوقيت. عرض غير متزامن - يحسّن الأداء بشكل طفيف عن طريق نقل عملية العرض إلى خيط معالجة منفصل لوحدة المعالجة المركزية. + يمكن لهذه الحيلة أن تزيد من الأداء عن طريق نقل عملية العرض إلى خيط معالجة منفصل على حساب مشاكل الرسوميات. استخدم التنظيف التفاعلي يحسن دقة العرض في بعض الألعاب على حساب الأداء. تمكين سجل التخزين المؤقت يُتيح هذا الخيار الوصول إلى حالات التخزين المؤقت السابقة. وقد يُحسّن جودة العرض وثبات الأداء في بعض الألعاب. مخازن الرؤوس المُحسّنة - يتيح ربط مخزن الرؤوس المُحسّن لتحسين الأداء. يتطلب برامج تشغيل Turnip/QCOM من إصدار Mesa 26.0 أو أحدث. سيؤدي إلى تعطل النظام عند استخدام برامج تشغيل Turnip الأقدم. + يُتيح ربطًا مُحسَّنًا لمخازن الرؤوس لتحسين الأداء. يتطلب برامج تشغيل Mesa 26.0+ Turnip/ برامج تشغيل QCOM. قد يتعطل على برامج تشغيل Turnip القديمة (25.3 وما دون). اختراقات @@ -505,6 +507,8 @@ يقلل من ضبابية التوهج في LA/EOW (Adreno A6XX - A7XX/ Turnip)، ويزيل التوهج في Burnout. تحذير: قد يسبب تشوهات رسومية في ألعاب أخرى. محاكاة BGR565 يُصلح مشاكل انعكاس الألوان في الألعاب أو ظهور تشوهات غريبة أو ظلال غريبة. + تفعيل ميزة إعادة التحجيم القديمة + يُمكّن هذا الخيار من التعامل مع عملية إعادة تحجيم الألعاب بطريقة تقليدية باستخدام مسار إعادة التحجيم السريع استخدم تظليل غير متزامن يقوم بتجميع التظليل بشكل غير متزامن. قد يقلل ذلك من التقطعات ولكنه قد يؤدي أيضًا إلى حدوث أخطاء. إعدادات إلغاء ترتيب بيانات وحدة معالجة الرسومات @@ -523,10 +527,10 @@ إضافات الحالة الديناميكية الموسعة - يتحكم هذا الخيار في عدد الميزات التي يمكن استخدامها في حالة الديناميكية الموسعة. تسمح الأرقام الأعلى بمزيد من الميزات ويمكن أن تزيد من الأداء، ولكنها قد تسبب مشاكل مع بعض برامج التشغيل والأجهزة. + يتحكم هذا الخيار في عدد الميزات التي يمكن استخدامها في ExtendedDynamicState (EDS). كلما زادت القيمة، قلّ عدد عمليات تجميع خط الأنابيب بناءً على الحالة الديناميكية التي يدعمها برنامج التشغيل. معطل حالة ديناميكية لإدخال الرأس - يتيح ميزة الحالة الديناميكية لإدخال الرأس لتحسين الجودة والأداء. + يتيح تمكين هذه الميزة معالجة أكثر مرونة لمدخلات الرؤوس، مما قد يقلل من وقت تجميع خط الأنابيب في vertex/buffer. تظليل العينة يسمح هذا الخيار بتنفيذ مُظلل الأجزاء لكل عينة في جزء متعدد العينات بدلاً من تنفيذه مرة واحدة لكل جزء. يُحسّن هذا من جودة الرسومات على حساب بعض الأداء. diff --git a/src/android/app/src/main/res/values-cs/strings.xml b/src/android/app/src/main/res/values-cs/strings.xml index 4f7d98057c..3354830611 100644 --- a/src/android/app/src/main/res/values-cs/strings.xml +++ b/src/android/app/src/main/res/values-cs/strings.xml @@ -478,10 +478,8 @@ Rozšíření Úroveň EDS - Určuje počet funkcí využívaných v rámci rozšířeného dynamického stavu API Vulkan (Extended Dynamic State). Vyšší hodnoty umožňují využít více funkcí a mohou zvýšit výkon, ale u některých ovladačů a výrobců grafických karet mohou způsobovat problémy s kompatibilitou. Vypnuto Dynamický stav vstupu vrcholů (Vertex Input) - Aktivuje funkci dynamického stavu vstupu vrcholů (Vertex Input Dynamic State) pro lepší kvalitu a výkon. Zobrazení Orientace diff --git a/src/android/app/src/main/res/values-de/strings.xml b/src/android/app/src/main/res/values-de/strings.xml index d2988d2b27..e7246dae2c 100644 --- a/src/android/app/src/main/res/values-de/strings.xml +++ b/src/android/app/src/main/res/values-de/strings.xml @@ -476,10 +476,8 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die Erweiterungen Erweiterter dynamischer Status - Steuert die Anzahl der Funktionen, die im \"Vertex Input Dynamic State\" werden können. Höhere Werte ermöglichen mehr Funktionen und können die Leistung steigern, können aber bei einigen Treibern und Anbietern zu Problemen führen. Deaktiviert Vertex Input Dynamic State - Aktiviert die Funktion \"Vertex Input Dynamic State\" für bessere Qualität und Leistung. Sample Shading Ermöglicht es dem Fragment-Shader, in einem Multisample-Fragment pro Sample anstatt einmal pro Fragment ausgeführt zu werden. Verbessert die Grafikqualität auf Kosten der Leistung. diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml index 35257c2beb..1abf996752 100644 --- a/src/android/app/src/main/res/values-es/strings.xml +++ b/src/android/app/src/main/res/values-es/strings.xml @@ -66,6 +66,8 @@ Muestra el consumo de energía actual y la capacidad restante de la batería Mostrar construcción de sombreadores Muestra el número actual de sombreadores que se están construyendo + Hilos de trabajo de canalización + Gestiona la cantidad de núcleos usados para la construcción de canalizaciones de Vulkan; un valor más alto mejorará el rendimiento de la contrucción de canalización, pero también aumentarán las temperaturas. Posición de la superposición Elige dónde se muestra la superposición en la pantalla Superior izquierda @@ -479,16 +481,14 @@ Forzar velocidad al máximo (solo Adreno) Fuerza a la GPU a ejecutarse a la velocidad máxima de reloj posible (se seguirán aplicando restricciones térmicas). Emulación de GPU asíncrona - Ejecuta la emulación de la GPU de forma asíncrona para reducir los bloqueos de la CPU y mejorar el rendimiento. Desactiva esta opción solo si experimentas problemas de sincronización. + Este hack puede aumentar el rendimiento ejecutando la emulación de la GPU de forma asíncrona, a costa de problemas gráficos y un aumento en la tasa de fallos debido a operaciones relacionadas con la sincronización. Presentación asíncrona - Mejora ligeramente el rendimiento al mover la presentación a un hilo independiente de la CPU. + Este hack puede aumentar el rendimiento al mover la presentación a un hilo independiente de la CPU a costa de problemas gráficos. Usar limpieza reactiva Mejora la precisión de renderizado en algunos juegos, pero reduce el rendimiento. Activar el historial del búfer Permite el acceso al estado del búfer anterior. Esta opción puede mejorar la calidad de renderizado y la consistencia en el rendimiento de algunos juegos. Búferes de vértices optimizados - Permite la optimización del enlace del búfer de vértices para un mejor rendimiento. Requiere controladores Mesa 26.0+ Turnip/ controladores QCOM. Causará fallos con controladores Turnip más antiguos. - Hacks Tiempo rápido de la GPU @@ -499,6 +499,7 @@ Reduce el efecto de resplandor en LA/EOW (Adreno A6XX - A7XX/ Turnip), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos. Emular BGR565 Soluciona problemas con colores invertidos en juegos, artefactos o sombras extrañas. + Activar la pasada de reescalado heredada Usar sombreadores asíncronos Compila los sombreadores de forma asíncrona. Esto puede reducir los tirones, pero también puede introducir errores gráficos. Ajustes de desentrelazado de la GPU @@ -517,10 +518,8 @@ Extensiones Estado dinámico extendido - Controla la cantidad de funciones que se pueden usar en el Estado Dinámico Extendido. Un número mayor permite más funciones y puede aumentar el rendimiento, pero puede causar problemas con algunos controladores y proveedores. Desactivado Estado dinámico de entrada de vértices - Activa la función de estado dinámico de entrada de vértices para una mejor calidad y rendimiento. Muestreo de sombreado Permite que el sombreador de fragmentos se ejecute por muestra en un fragmento multimuestreado, en lugar de una sola vez por fragmento. Mejora la calidad de los gráficos a coste de algo de rendimiento. diff --git a/src/android/app/src/main/res/values-fr/strings.xml b/src/android/app/src/main/res/values-fr/strings.xml index 0f41841fb5..d7f77337cf 100644 --- a/src/android/app/src/main/res/values-fr/strings.xml +++ b/src/android/app/src/main/res/values-fr/strings.xml @@ -483,7 +483,6 @@ État dynamique étendu Désactivé État dynamique d\'entrée de sommet - Active la fonctionnalité d\'état dynamique des entrées de sommets pour une meilleure qualité et de meilleures performances. Affichage Orientation diff --git a/src/android/app/src/main/res/values-pl/strings.xml b/src/android/app/src/main/res/values-pl/strings.xml index ac09657d6c..40a2035200 100644 --- a/src/android/app/src/main/res/values-pl/strings.xml +++ b/src/android/app/src/main/res/values-pl/strings.xml @@ -476,10 +476,8 @@ Rozszerzenia Rozszerzony stan dynamiczny - Kontroluje liczbę funkcji, które mogą być używane w Extended Dynamic State. Wyższe wartości pozwalają na użycie większej liczby funkcji i mogą zwiększyć wydajność, ale mogą powodować problemy z niektórymi sterownikami i u niektórych producentów. Wyłączone Dynamiczny stan wejścia wierzchołków - Włącza funkcję dynamicznego stanu wejścia wierzchołków, poprawiając jakość i wydajność. Cieniowanie próbkowane Pozwala uruchamiać shader fragmentów dla każdej próbki w wielopróbkowanym fragmencie zamiast raz na fragment. Poprawia jakość grafiki kosztem części wydajności. diff --git a/src/android/app/src/main/res/values-pt-rBR/strings.xml b/src/android/app/src/main/res/values-pt-rBR/strings.xml index d87d6a15e6..e631d3566f 100644 --- a/src/android/app/src/main/res/values-pt-rBR/strings.xml +++ b/src/android/app/src/main/res/values-pt-rBR/strings.xml @@ -463,7 +463,6 @@ Extended Dynamic State Desativado Vertex Input Dynamic State - Ativa o recurso de vertex input dynamic state para melhor qualidade e desempenho. Tela Orientação diff --git a/src/android/app/src/main/res/values-ru/strings.xml b/src/android/app/src/main/res/values-ru/strings.xml index dbce577e13..4e5f2149e8 100644 --- a/src/android/app/src/main/res/values-ru/strings.xml +++ b/src/android/app/src/main/res/values-ru/strings.xml @@ -66,6 +66,8 @@ Показать текущее энергопотребление и оставшуюся емкость аккумулятора Показать компиляцию шейдеров Отображает текущее количество шейдеров, которые компилируются + Рабочие потоки конвейера + Позволяет настроить количество ядер, задействованных при построении конвейеров Vulkan. Чем выше значение, тем быстрее будет компиляция конвейеров, однако это приведёт к повышению температуры устройства. Позиция оверлея Расположение оверлея на экране Сверху слева @@ -481,15 +483,15 @@ Принудительная максимальная тактовая частота (только для Adreno) Заставляет ГПУ работать на максимально возможных тактовых частотах (тепловые ограничения все равно будут применяться). Асинхронная эмуляция ГПУ - Выполняет эмуляцию ГПУ асинхронно для снижения задержек ЦП и увеличения производительности. Отключайте только при возникновении проблем с таймингами. + Может повысить производительность за счёт асинхронного запуска эмуляции ГПУ, но ценой появления графических ошибок и увеличения частоты вылетов из-за операций, зависящих от синхронизации. Асинхронная презентация - Немного улучшает производительность, перемещая презентацию в отдельный поток ЦП. + Может повысить производительность за счёт перемещения вывода кадров в отдельный поток ЦП, но ценой возникновения графических проблем. Реактивная очистка Повышение точности рендеринга в некоторых играх за счет снижения производительности. Включить историю буфера Позволяет обращаться к предыдущим состояниям буфера. Эта опция может повысить качество рендеринга и стабильность производительности в некоторых играх. Оптимизированные вершинные буферы - Включает оптимизированную привязку вершинного буфера для повышения производительности. Требует Mesa Turnip 26.0+ / QCOM драйверы. Приводит к вылету на старых версиях Turnip. + Включает оптимизированную привязку вершинного буфера для повышения производительности. Требует Mesa Turnip 26.0+ / QCOM. Приводит к вылету на старых версиях драйверов Turnip (25.3 и ниже). Хаки @@ -501,6 +503,8 @@ Частично убирает размытие в LA/EOW (Adreno A6XX - A7XX/ Turnip), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх. Эмулировать BGR565 Исправляет проблемы с инвертированными цветами в играх, а также со странными артефактами или некорректными тенями. + Включить старый метод изменения разрешения + Включает старый метод обработки этапа перенастройки масштабирования для игр за счёт использования быстрого алгоритма перемасштабирования. Использовать асинхронные шейдеры Компилирует шейдеры асинхронно. Это может уменьшить подтормаживания, но также может вызвать графические артефакты. Настройки распаковки текстур (Unswizzle) @@ -519,10 +523,10 @@ Расширения Расширенное динамическое состояние - Управляет количеством функций, доступных в режиме «Расширенное динамическое состояние». Большее число позволяет задействовать больше функций и может повысить производительность, но способно вызывать проблемы с некоторыми драйверами и графикой. + Управляет количеством функций, доступных для использования в расширенном динамическом состояние. Более высокое значение позволит сократить количество компиляций конвейеров за счёт поддержки динамического состояния драйвером. Отключено Динамическое состояние ввода вершин - Включает функцию динамического состояния ввода вершин для повышения качества и производительности + Включение этой функции обеспечивает более гибкую обработку входных данных вершин, что потенциально сокращает время компиляции конвейера на этапе работы с вершинами и буферами. Сэмпловое затенение Позволяет шейдеру фрагментов выполняться для каждого сэмпла в многосэмпловом фрагменте, а не один раз на фрагмент. Улучшает качество графики ценой некоторого падения производительности. @@ -1155,4 +1159,6 @@ Высококачественное масштабирование от AMD Дополнительный контент Добавить папку - + %1$d %% + + diff --git a/src/android/app/src/main/res/values-uk/strings.xml b/src/android/app/src/main/res/values-uk/strings.xml index 3338d48d68..cbf4211bac 100644 --- a/src/android/app/src/main/res/values-uk/strings.xml +++ b/src/android/app/src/main/res/values-uk/strings.xml @@ -66,6 +66,8 @@ Показати поточне споживання енергії та залишкову ємність акумулятора Показати побудову шейдерів Показати поточну кількість шейдерів, які наразі компілюються + Потоки обробника конвеєра + Керує кількістю ядер, що використовуються для збірки конвеєрів Vulkan. Вище значення покращить продуктивність компіляції конвеєра, але також підвищить температуру. Позиція оверлею Обрати розташування виводу статистики на екрані Вгорі ліворуч @@ -481,15 +483,15 @@ Максимальна тактова частота (тільки Adreno) Змушує GPU працювати на максимальній тактовій частоті. Асинхронна емуляція ГП - Емуляція ГП виконується асинхронно для зменшення затримок ЦП й покращення пропускної здатності. Вимкніть лише у випадку виникнення проблем із таймінгами. + Це обхідне рішення може покращити продуктивність завдяки асинхронному виконанню емуляції ГП, але спричинить проблеми з графікою та збільшить частоту збоїв чутливих до таймінгів операцій. Асинхронне подання - Трохи покращує продуктивність завдяки переміщенню подання на окремий потік ЦП. + Це обхідне рішення може покращити продуктивність завдяки переміщенню подання на окремий потік ЦП, але спричинить проблеми з графікою. Реактивне очищення Покращує точність рендерингу в деяких іграх. Увімкнути історію буфера Вмикає доступ до попередніх станів буфера. Цей параметр може покращити якість візуалізації та стабільну продуктивність у деяких іграх. Оптимізовані буфери вершин - Застосовує оптимізований буфер вершин, щоб покращити продуктивність. Потребує драйверів Mesa 26.0+ Turnip / QCOM. На старіших драйверах Turnip виникатиме збій. + Застосовує оптимізований буфер вершин, щоб покращити продуктивність. Потребує драйверів Mesa 26.0+ Turnip / QCOM. На старіших драйверах Turnip виникатиме збій (25.3 і нижче). Обхідні рішення @@ -501,6 +503,8 @@ Зменшує розмиття світіння в LA/EOW (Adreno A6XX–A7XX / Turnip), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх. Емулювати BGR565 Виправляє проблеми з інвертованими кольорами в іграх або дивними артефактами чи тінями. + Увімкнути застаріле масштабування + Вмикає застарілу обробку масштабування для ігор, використовуючи швидкий шлях масштабування Асинхронні шейдери Компілює шейдери асинхронно. Це може зменшити затримки, але також може спричинити графічні баги. Налаштування розпакування за допомогою ГП @@ -519,10 +523,10 @@ Розширення Розширений динамічний стан - Керує кількістю функцій, які можна використовувати в «Розширеному динамічному стані». Вище число дозволяє більше функцій і може покращити продуктивність, але може спричинити проблеми з деякими драйверами й виробниками. + Керує кількістю функцій, які можна використовувати в ExtendedDynamicState (EDS). Вище значення дозволить зменшити кількість компіляцій конвеєра на основі динамічного стану, підтримуваного драйвером. Вимкнено Динамічний стан введення вершин - Вмикає можливість динамічного стану введення вершин для кращих якості й продуктивності. + Увімкнення цієї функції дозволить гнучкішу обробку введення вершин. Може зменшити час компіляції конвеєра для вершин/буфера. Простий шейдинг Дозволяє виконувати фрагмент шейдера для кожного зразка в багатозразковому фрагменті замість одного разу для кожного фрагмента. Покращує якість графікі ціною втрати продуктивності. diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml index 7777b40767..bedc53dc43 100644 --- a/src/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml @@ -475,16 +475,12 @@ 强制最大时钟 (仅限 Adreno) 强制 GPU 以最大时钟运行 (仍被温控限制)。 GPU 异步模拟 - 异步运行 GPU 模拟,以减少 CPU 停顿并提高吞吐量。仅当遇到与时序相关的问题时才应禁用此功能。 异步呈现 - 通过将呈现操作移至单独的 CPU 线程来略微提升性能。 启用反应性刷新 通过牺牲性能来提高某些游戏的渲染精度。 启用缓冲区历史 启用对先前缓冲区状态的访问。此选项可在某些游戏中提升渲染质量并保持性能的一致性。 优化顶点缓冲区 - 启用经过优化的顶点缓冲区绑定以提升性能。需要 Mesa 26.0 及以上版本的 Turnip 或 QCOM 驱动程序。若使用较旧版本的 Turnip 驱动则会导致崩溃。 - Hacks GPU 超频频率 @@ -513,10 +509,8 @@ 扩展 扩展动态状态 - 控制在扩展动态状态中可使用的函数数量。更高的数值允许启用更多功能,并可能提升性能,但同时也可能导致额外的图形问题。 已禁用 顶点输入动态状态 - 开启顶点输入动态状态功能来获得更好的质量和性能。 采样着色 允许片段着色器在多采样片段中每个样本执行一次,而不是每个片段执行一次。以提高性能为代价改善图形质量。 diff --git a/src/android/app/src/main/res/values-zh-rTW/strings.xml b/src/android/app/src/main/res/values-zh-rTW/strings.xml index d45059a3b0..dd56e9968d 100644 --- a/src/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/android/app/src/main/res/values-zh-rTW/strings.xml @@ -466,7 +466,6 @@ 擴展動態狀態 已停用 頂點輸入動態狀態 - 啟用頂點輸入動態狀態以取得更佳的品質及性能 顯示 方向 From 28a2ff1b9474c673ba3acb266aaf18b344321dbe Mon Sep 17 00:00:00 2001 From: smiRaphi Date: Wed, 13 May 2026 19:13:44 +0200 Subject: [PATCH 31/58] [file_sys] fix romfs_ext mods (#3914) Makes them show up in the menu & also let's them load from SDMC Note: the android edit is totally untested and I've no clue of Kotlin but I don't see a reason why it shouldn't work Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3914 Reviewed-by: crueter --- .../java/org/yuzu/yuzu_emu/utils/AddonUtil.kt | 4 ++-- src/core/file_sys/patch_manager.cpp | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/AddonUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/AddonUtil.kt index b5613a7a76..60bdaefe9b 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/AddonUtil.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/AddonUtil.kt @@ -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 @@ -7,5 +7,5 @@ package org.yuzu.yuzu_emu.utils object AddonUtil { - val validAddonDirectories = listOf("cheats", "exefs", "romfs", "romfslite") + val validAddonDirectories = listOf("cheats", "exefs", "romfs", "romfslite", "romfs_ext") } diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 6af926eac0..80372ec94e 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -569,12 +569,11 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t layers.emplace_back(std::move(extracted)); auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers)); - if (layered == nullptr) { + auto layered_ext = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers_ext)); + if (layered == nullptr && layered_ext == nullptr) { return; } - auto layered_ext = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers_ext)); - auto packed = CreateRomFS(std::move(layered), std::move(layered_ext)); if (packed == nullptr) { return; @@ -943,6 +942,8 @@ std::vector PatchManager::GetPatches(VirtualFile update_raw) const { if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(mod, "romfs")) || IsDirValidAndNonEmpty(FindSubdirectoryCaseless(mod, "romfslite"))) AppendCommaIfNotEmpty(types, "LayeredFS"); + if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(mod, "romfs_ext"))) + AppendCommaIfNotEmpty(types, "ExtLayeredFS"); if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(mod, "cheats"))) AppendCommaIfNotEmpty(types, "Cheats"); @@ -965,13 +966,13 @@ std::vector PatchManager::GetPatches(VirtualFile update_raw) const { const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); if (sdmc_mod_dir != nullptr) { std::string types; - if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "exefs"))) { + if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "exefs"))) AppendCommaIfNotEmpty(types, "LayeredExeFS"); - } if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs")) || - IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfslite"))) { + IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfslite"))) AppendCommaIfNotEmpty(types, "LayeredFS"); - } + if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs_ext"))) + AppendCommaIfNotEmpty(types, "ExtLayeredFS"); if (!types.empty()) { const auto mod_disabled = From 1f558ce9b3ae5feb5c56dbc1fe9825cfb8470f05 Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 13 May 2026 19:14:18 +0200 Subject: [PATCH 32/58] [vk, ogl] bump shader cache version to 17 (#3947) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3947 Reviewed-by: MaranBr Reviewed-by: crueter --- src/video_core/renderer_opengl/gl_shader_cache.cpp | 2 +- src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 9275dbf01c..deedf1aa6b 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -54,7 +54,7 @@ using VideoCommon::LoadPipelines; using VideoCommon::SerializePipeline; using Context = ShaderContext::Context; -constexpr u32 CACHE_VERSION = 14; +constexpr u32 CACHE_VERSION = 15; template auto MakeSpan(Container& container) { diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index d3a98f1a1c..d0f98091c1 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -62,7 +62,7 @@ using VideoCommon::FileEnvironment; using VideoCommon::GenericEnvironment; using VideoCommon::GraphicsEnvironment; -constexpr u32 CACHE_VERSION = 16; +constexpr u32 CACHE_VERSION = 17; constexpr std::array VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'}; template From ee188168c12188340961314e1dfc70a4f7ad4f7a Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 13 May 2026 19:14:59 +0200 Subject: [PATCH 33/58] [common] do not crash when don't have permissions to /tmp/eden directory due to unforessen circumstances (FreeBSD) (#3912) instead of throwing, use std::error_code and such due to reasons unberknownst to me, the UID of the /tmp/eden directory was set for another user, this inevitably caused a crash due to wrong permissions (which is a very user unfriendly thing to do generally) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3912 Reviewed-by: crueter --- src/frontend_common/data_manager.cpp | 6 +++--- src/qt_common/util/content.cpp | 10 ++++------ src/qt_common/util/mod.cpp | 11 ++++++----- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/frontend_common/data_manager.cpp b/src/frontend_common/data_manager.cpp index 280cbba4ab..e4e9a32ce1 100644 --- a/src/frontend_common/data_manager.cpp +++ b/src/frontend_common/data_manager.cpp @@ -46,10 +46,10 @@ const std::string GetDataDirString(DataDir dir, const std::string &user_id) u64 ClearDir(DataDir dir, const std::string &user_id) { fs::path data_dir = GetDataDir(dir, user_id); - u64 result = fs::remove_all(data_dir); - + std::error_code ec; + u64 result = fs::remove_all(data_dir, ec); // mkpath at the end just so it actually exists - fs::create_directories(data_dir); + fs::create_directories(data_dir, ec); return result; } diff --git a/src/qt_common/util/content.cpp b/src/qt_common/util/content.cpp index 4d9b324608..f705b3e00f 100644 --- a/src/qt_common/util/content.cpp +++ b/src/qt_common/util/content.cpp @@ -181,15 +181,13 @@ void InstallFirmware(const QString& location, bool recursive) { QString UnzipFirmwareToTmp(const QString& location) { namespace fs = std::filesystem; - fs::path tmp{fs::temp_directory_path()}; - - if (!fs::create_directories(tmp / "eden" / "firmware")) { + fs::path tmp{fs::temp_directory_path() / "eden" / "firmware"}; + std::error_code ec; + fs::remove_all(tmp, ec); + if (!fs::create_directories(tmp, ec)) { return QString(); } - tmp /= "eden"; - tmp /= "firmware"; - QString qCacheDir = QString::fromStdString(tmp.string()); QFile zip(location); diff --git a/src/qt_common/util/mod.cpp b/src/qt_common/util/mod.cpp index 4e7fd54e79..3e75cb21fa 100644 --- a/src/qt_common/util/mod.cpp +++ b/src/qt_common/util/mod.cpp @@ -83,8 +83,9 @@ QStringList GetModFolders(const QString& root, const QString& fallbackName) { // now make a temp directory... const auto mod_dir = fs::temp_directory_path() / "eden" / "mod" / name.toStdString(); const auto tmp = mod_dir / to_make; - fs::remove_all(mod_dir); - if (!fs::create_directories(tmp)) { + std::error_code ec; + fs::remove_all(mod_dir, ec); + if (!fs::create_directories(tmp, ec)) { LOG_ERROR(Frontend, "Failed to create temporary directory {}", tmp.string()); return {}; } @@ -116,9 +117,9 @@ QStringList GetModFolders(const QString& root, const QString& fallbackName) { const QString ExtractMod(const QString& path) { namespace fs = std::filesystem; fs::path tmp{fs::temp_directory_path() / "eden" / "unzip_mod"}; - - fs::remove_all(tmp); - if (!fs::create_directories(tmp)) { + std::error_code ec; + fs::remove_all(tmp, ec); + if (!fs::create_directories(tmp, ec)) { QtCommon::Frontend::Critical(tr("Mod Extract Failed"), tr("Failed to create temporary directory %1") .arg(QString::fromStdString(tmp.string()))); From d1ceeeca229383ed44b74d4d9d248c50359d5b58 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 14 May 2026 00:17:13 +0200 Subject: [PATCH 34/58] [cmake] use -mtls-dialect=gnu2 (#3948) see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120933 we use TLS very sparingly (which is a good thing), some of our dependencies, in turn, may not we should be aware of that fact allegedly, there are minor glibc issues and such, but most distros should be fine additionally, this is only enabled for FreeBSD and Linux, if it works on FreeBSD, naturally every Linux distro should support it as well Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3948 Reviewed-by: CamilleLaVey Reviewed-by: Maufeat --- src/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 48544aeaec..58ae00e8d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -159,7 +159,10 @@ else() endif() if (ARCHITECTURE_x86_64) - add_compile_options(-mcx16) + add_compile_options($<$:-mcx16>) + if (PLATFORM_LINUX OR PLATFORM_FREEBSD) + add_compile_options($<$:-mtls-dialect=gnu2>) + endif() endif() if (APPLE AND CXX_CLANG) From bc9b9480fbbde8ee6ad2fc118e9f0afc96dd65ec Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 15 May 2026 22:01:42 +0200 Subject: [PATCH 35/58] [dynarmic] fix 12th-gen Intel CPUs crashing due to UMONITOR (#3954) see https://github.com/herumi/xbyak/issues/255 > Proof: https://godbolt.org/z/9vseq4Ynj > Xbyak currently implements it as: > ```c++ > void umonitor(const Reg& r) { > int idx = r.getIdx(); > if (idx > 7) XBYAK_THROW(ERR_BAD_PARAMETER) //umonitor DOES accept r8,r9,r10,etc this is NOT correct > int bit = r.getBit(); > if (BIT != bit) { > if ((BIT == 32 && bit == 16) || (BIT == 64 && bit == 32)) { > db(0x67); > } else { > XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) > } > } > db(0xF3); db(0x0F); db(0xAE); setModRM(3, 6, idx); > } > ``` > My program was throwing Xbyak::Exception and I tracked it down to this particular umonitor Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3954 Reviewed-by: crueter Reviewed-by: MaranBr --- src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp index e3f1721132..1a80ae638a 100644 --- a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp +++ b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp @@ -26,6 +26,7 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 Xbyak::Label start, loop; code.jmp(start, code.T_NEAR); code.L(loop); + if (waitpkg) { // TODO: this is because we lack regalloc - so better to be safe :( code.push(Xbyak::util::rax); @@ -33,7 +34,14 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 code.push(Xbyak::util::rdx); // TODO: This clobbers EAX and EDX did we tell the regalloc? // ARM ptr for address-monitoring - code.umonitor(ptr); + + // XBYAK BUG: code.umonitor(ptr); see issue #255 + // replace once xbyak has been fixed + code.db(0xF3); + if (ptr.getIdx() >= 8) code.db(0x41); + code.db(0x0F); code.db(0xAE); + code.db(uint8_t((3 << 6) | ((6 & 7) << 3) | (ptr.getIdx() & 7))); + // tmp.bit[0] = 0: C0.1 | Slow Wakup | Better Savings // tmp.bit[0] = 1: C0.2 | Fast Wakup | Lesser Savings // edx:eax is implicitly used as a 64-bit deadline timestamp From 02dee4a20b7edbe094e7428f3b4f59bacbaa043f Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 15 May 2026 22:05:32 +0200 Subject: [PATCH 36/58] [file_sys/system_archive] remove uneeded ctor/dtor initializations for std::map<> when creating system archives for nx_tzdb generated files (#3919) sounds like word salad but let me say: - std::map<> created a static ctor for EVERY SINGLE ZONEINFO - fuck that, instead lets just use a raw array and construct things statically - works the same except with less baggage carried around (+ less heap allocations!!!) this should help reduce codesize due to the aforementioned global ctor/dtor Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3919 Reviewed-by: crueter --- externals/nx_tzdb/NxTzdbCreateHeader.cmake | 27 ++++-- externals/nx_tzdb/tzdb_template.h.in | 6 +- .../system_archive/time_zone_binary.cpp | 96 ++++++------------- 3 files changed, 53 insertions(+), 76 deletions(-) diff --git a/externals/nx_tzdb/NxTzdbCreateHeader.cmake b/externals/nx_tzdb/NxTzdbCreateHeader.cmake index 95606d8629..229c8aa43d 100644 --- a/externals/nx_tzdb/NxTzdbCreateHeader.cmake +++ b/externals/nx_tzdb/NxTzdbCreateHeader.cmake @@ -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 @@ -16,15 +19,24 @@ if (NOT FILE_LIST) endif() set(DIRECTORY_NAME ${HEADER_NAME}) - set(FILE_DATA "") + +string(APPEND FILE_DATA "[[nodiscard]] static inline std::vector CollectFiles_${DIRECTORY_NAME}() {\n") +string(APPEND FILE_DATA [[ + std::vector vfs_files; + auto const fn = [&](std::string_view name, std::span data) { + vfs_files.push_back(std::make_shared( + std::vector(data.begin(), data.end()), + std::string{name} + )); + }; +]]) foreach(ZONE_FILE ${FILE_LIST}) if (ZONE_FILE STREQUAL "\n") continue() endif() - - string(APPEND FILE_DATA "{\"${ZONE_FILE}\",\n{") - + string(APPEND FILE_DATA " {\n") + string(APPEND FILE_DATA " constexpr uint8_t tzdb_data[] = {\n") file(READ ${ZONE_PATH}/${ZONE_FILE} ZONE_DATA HEX) string(LENGTH "${ZONE_DATA}" ZONE_DATA_LEN) foreach(I RANGE 0 ${ZONE_DATA_LEN} 2) @@ -42,9 +54,12 @@ foreach(ZONE_FILE ${FILE_LIST}) string(APPEND FILE_DATA " ") endif() endforeach() - - string(APPEND FILE_DATA "}},\n") + string(APPEND FILE_DATA " };\n") + string(APPEND FILE_DATA " fn(\"${ZONE_FILE}\", tzdb_data);\n") + string(APPEND FILE_DATA " }\n") endforeach() +string(APPEND FILE_DATA " return vfs_files;\n") +string(APPEND FILE_DATA "}\n") file(READ ${NX_TZDB_SOURCE_DIR}/tzdb_template.h.in NX_TZDB_TEMPLATE_H_IN) file(CONFIGURE OUTPUT ${NX_TZDB_INCLUDE_DIR}/nx_tzdb/${HEADER_NAME}.h CONTENT "${NX_TZDB_TEMPLATE_H_IN}") diff --git a/externals/nx_tzdb/tzdb_template.h.in b/externals/nx_tzdb/tzdb_template.h.in index 289d002ea8..d7907b846d 100644 --- a/externals/nx_tzdb/tzdb_template.h.in +++ b/externals/nx_tzdb/tzdb_template.h.in @@ -9,10 +9,10 @@ namespace NxTzdb { +// @DIRECTORY_NAME@ + // clang-format off -const static std::map> @DIRECTORY_NAME@ = -{ -@FILE_DATA@}; +@FILE_DATA@ // clang-format on } // namespace NxTzdb diff --git a/src/core/file_sys/system_archive/time_zone_binary.cpp b/src/core/file_sys/system_archive/time_zone_binary.cpp index 316ff0dc6f..9b79b6fcd3 100644 --- a/src/core/file_sys/system_archive/time_zone_binary.cpp +++ b/src/core/file_sys/system_archive/time_zone_binary.cpp @@ -1,86 +1,48 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include "common/swap.h" #include "core/file_sys/system_archive/time_zone_binary.h" +#include "core/file_sys/vfs/vfs_static.h" +#include "core/file_sys/vfs/vfs_types.h" #include "core/file_sys/vfs/vfs_vector.h" #include "nx_tzdb.h" namespace FileSys::SystemArchive { -const static std::map>&> - tzdb_zoneinfo_dirs = {{"Africa", NxTzdb::africa}, - {"America", NxTzdb::america}, - {"Antarctica", NxTzdb::antarctica}, - {"Arctic", NxTzdb::arctic}, - {"Asia", NxTzdb::asia}, - {"Atlantic", NxTzdb::atlantic}, - {"Australia", NxTzdb::australia}, - {"Brazil", NxTzdb::brazil}, - {"Canada", NxTzdb::canada}, - {"Chile", NxTzdb::chile}, - {"Etc", NxTzdb::etc}, - {"Europe", NxTzdb::europe}, - {"Indian", NxTzdb::indian}, - {"Mexico", NxTzdb::mexico}, - {"Pacific", NxTzdb::pacific}, - {"US", NxTzdb::us}}; - -const static std::map>&> - tzdb_america_dirs = {{"Argentina", NxTzdb::america_argentina}, - {"Indiana", NxTzdb::america_indiana}, - {"Kentucky", NxTzdb::america_kentucky}, - {"North_Dakota", NxTzdb::america_north_dakota}}; - -static void GenerateFiles(std::vector& directory, - const std::map>& files) { - for (const auto& [filename, data] : files) { - const auto data_copy{data}; - const std::string filename_copy{filename}; - VirtualFile file{ - std::make_shared(std::move(data_copy), std::move(filename_copy))}; - directory.push_back(file); - } -} - -static std::vector GenerateZoneinfoFiles() { - std::vector zoneinfo_files; - GenerateFiles(zoneinfo_files, NxTzdb::zoneinfo); - return zoneinfo_files; -} - VirtualDir TimeZoneBinary() { std::vector america_sub_dirs; - for (const auto& [dir_name, files] : tzdb_america_dirs) { - std::vector vfs_files; - GenerateFiles(vfs_files, files); - america_sub_dirs.push_back(std::make_shared( - std::move(vfs_files), std::vector{}, dir_name)); - } - + america_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_america_argentina(), std::vector{}, "Argentina")); + america_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_america_indiana(), std::vector{}, "Indiana")); + america_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_america_kentucky(), std::vector{}, "Kentucky")); + america_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_america_north_dakota(), std::vector{}, "North_Dakota")); std::vector zoneinfo_sub_dirs; - for (const auto& [dir_name, files] : tzdb_zoneinfo_dirs) { - std::vector vfs_files; - GenerateFiles(vfs_files, files); - if (dir_name == "America") { - zoneinfo_sub_dirs.push_back(std::make_shared( - std::move(vfs_files), std::move(america_sub_dirs), dir_name)); - } else { - zoneinfo_sub_dirs.push_back(std::make_shared( - std::move(vfs_files), std::vector{}, dir_name)); - } - } - - std::vector zoneinfo_dir{std::make_shared( - GenerateZoneinfoFiles(), std::move(zoneinfo_sub_dirs), "zoneinfo")}; - std::vector root_files; - GenerateFiles(root_files, NxTzdb::base); - - return std::make_shared(std::move(root_files), std::move(zoneinfo_dir), - "data"); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_africa(), std::vector{}, "Africa")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_america(), std::move(america_sub_dirs), "America")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_antarctica(), std::vector{}, "Antarctica")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_arctic(), std::vector{}, "Arctic")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_asia(), std::vector{}, "Asia")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_atlantic(), std::vector{}, "Atlantic")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_australia(), std::vector{}, "Australia")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_brazil(), std::vector{}, "Brazil")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_canada(), std::vector{}, "Canada")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_chile(), std::vector{}, "Chile")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_etc(), std::vector{}, "Etc")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_europe(), std::vector{}, "Europe")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_indian(), std::vector{}, "Indian")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_mexico(), std::vector{}, "Mexico")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_pacific(), std::vector{}, "Pacific")); + zoneinfo_sub_dirs.push_back(std::make_shared(NxTzdb::CollectFiles_us(), std::vector{}, "US")); + std::vector zoneinfo_dir{std::make_shared(NxTzdb::CollectFiles_zoneinfo(), std::move(zoneinfo_sub_dirs), "zoneinfo")}; + // last files (root) + return std::make_shared(NxTzdb::CollectFiles_base(), std::move(zoneinfo_dir), "data"); } } // namespace FileSys::SystemArchive From a1f9e68f46c729a49eeaec1a81d9ac26145d2509 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 15 May 2026 22:06:23 +0200 Subject: [PATCH 37/58] [hid_core] remove contentious mutex from EmulatedController and just rely on atomic semantics for fields (#3866) inputs shouldnt be that critical to require a full mutex of them this relies on CPU guaranteeing u32/u16/u8 atomic load/stores for EmulatedController fields, which works on x86_64 but may not have the same behaviour on other architectures - thats why i wrap them in `std::atomic<>` Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3866 Reviewed-by: crueter --- src/hid_core/frontend/emulated_controller.cpp | 178 +++++------------- src/hid_core/frontend/emulated_controller.h | 26 +-- 2 files changed, 60 insertions(+), 144 deletions(-) diff --git a/src/hid_core/frontend/emulated_controller.cpp b/src/hid_core/frontend/emulated_controller.cpp index 604414c470..ef841e2411 100644 --- a/src/hid_core/frontend/emulated_controller.cpp +++ b/src/hid_core/frontend/emulated_controller.cpp @@ -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: Copyright 2021 yuzu Emulator Project @@ -108,10 +108,10 @@ void EmulatedController::ReloadFromSettings() { // Other or debug controller should always be a pro controller if (npad_id_type != NpadIdType::Other) { SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type)); - original_npad_type = npad_type; + original_npad_type = npad_type.load(); } else { SetNpadStyleIndex(NpadStyleIndex::Fullkey); - original_npad_type = npad_type; + original_npad_type = npad_type.load(); } // Disable special features before disconnecting @@ -577,10 +577,9 @@ void EmulatedController::UnloadInput() { } void EmulatedController::EnableConfiguration() { - std::unique_lock lock1{connect_mutex}, lock2{npad_mutex}; - is_configuring = true; - tmp_is_connected = is_connected; - tmp_npad_type = npad_type; + is_configuring.store(true); + tmp_is_connected.store(is_connected); + tmp_npad_type.store(npad_type); } void EmulatedController::DisableConfiguration() { @@ -600,7 +599,7 @@ void EmulatedController::DisableConfiguration() { Disconnect(); } SetNpadStyleIndex(tmp_npad_type); - original_npad_type = tmp_npad_type; + original_npad_type.store(tmp_npad_type); } // Apply temporary connected status to the real controller @@ -614,19 +613,16 @@ void EmulatedController::DisableConfiguration() { } void EmulatedController::EnableSystemButtons() { - std::unique_lock lock{mutex}; system_buttons_enabled = true; } void EmulatedController::DisableSystemButtons() { - std::unique_lock lock{mutex}; system_buttons_enabled = false; controller.home_button_state.raw = 0; controller.capture_button_state.raw = 0; } void EmulatedController::ResetSystemButtons() { - std::unique_lock lock{mutex}; controller.home_button_state.home.Assign(false); controller.capture_button_state.capture.Assign(false); } @@ -763,8 +759,7 @@ void EmulatedController::StartMotionCalibration() { } } -void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, - Common::UUID uuid) { +void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, Common::UUID uuid) { const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type); const auto& player = Settings::values.players.GetValue()[player_index]; @@ -772,7 +767,6 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback return; } - std::unique_lock lock{mutex}; bool value_changed = false; const auto new_status = TransformToButton(callback); auto& current_status = controller.button_values[index]; @@ -818,7 +812,6 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback controller.debug_pad_button_state.raw = 0; controller.home_button_state.raw = 0; controller.capture_button_state.raw = 0; - lock.unlock(); TriggerOnChange(ControllerTriggerType::Button, false); return; } @@ -922,8 +915,6 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback break; } - lock.unlock(); - if (!is_connected) { if (npad_type == NpadStyleIndex::Handheld) { if (npad_id_type == NpadIdType::Handheld) { @@ -952,7 +943,6 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, auto trigger_guard = SCOPE_GUARD { TriggerOnChange(ControllerTriggerType::Stick, !is_configuring); }; - std::unique_lock lock{mutex}; const auto stick_value = TransformToStick(callback); // Only read stick values that have the same uuid or are over the threshold to avoid flapping @@ -1009,7 +999,6 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac auto trigger_guard = SCOPE_GUARD { TriggerOnChange(ControllerTriggerType::Trigger, !is_configuring); }; - std::unique_lock lock{mutex}; const auto trigger_value = TransformToTrigger(callback); // Only read trigger values that have the same uuid or are pressed once @@ -1057,7 +1046,6 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback SCOPE_EXIT { TriggerOnChange(ControllerTriggerType::Motion, !is_configuring); }; - std::unique_lock lock{mutex}; auto& raw_status = controller.motion_values[index].raw_status; auto& emulated = controller.motion_values[index].emulated; @@ -1093,7 +1081,6 @@ void EmulatedController::SetColors(const Common::Input::CallbackStatus& callback auto trigger_guard = SCOPE_GUARD { TriggerOnChange(ControllerTriggerType::Color, !is_configuring); }; - std::unique_lock lock{mutex}; controller.color_values[index] = TransformToColor(callback); if (is_configuring) { @@ -1136,15 +1123,13 @@ void EmulatedController::SetColors(const Common::Input::CallbackStatus& callback } } -void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback, - std::size_t index) { +void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback, std::size_t index) { if (index >= controller.battery_values.size()) { return; } SCOPE_EXIT { TriggerOnChange(ControllerTriggerType::Battery, !is_configuring); }; - std::unique_lock lock{mutex}; controller.battery_values[index] = TransformToBattery(callback); if (is_configuring) { @@ -1209,47 +1194,33 @@ void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback SCOPE_EXIT { TriggerOnChange(ControllerTriggerType::IrSensor, !is_configuring); }; - std::unique_lock lock{mutex}; controller.camera_values = TransformToCamera(callback); - - if (is_configuring) { - return; + if (!is_configuring) { + controller.camera_state.sample++; + controller.camera_state.format = Core::IrSensor::ImageTransferProcessorFormat(controller.camera_values.format); + controller.camera_state.data = controller.camera_values.data; } - - controller.camera_state.sample++; - controller.camera_state.format = - static_cast(controller.camera_values.format); - controller.camera_state.data = controller.camera_values.data; } void EmulatedController::SetRingAnalog(const Common::Input::CallbackStatus& callback) { SCOPE_EXIT { TriggerOnChange(ControllerTriggerType::RingController, !is_configuring); }; - std::unique_lock lock{mutex}; const auto force_value = TransformToStick(callback); - controller.ring_analog_value = force_value.x; - - if (is_configuring) { - return; + if (!is_configuring) { + controller.ring_analog_state.force = force_value.x.value; } - - controller.ring_analog_state.force = force_value.x.value; } void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) { SCOPE_EXIT { TriggerOnChange(ControllerTriggerType::Nfc, !is_configuring); }; - std::unique_lock lock{mutex}; controller.nfc_values = TransformToNfc(callback); - - if (is_configuring) { - return; + if (!is_configuring) { + controller.nfc_state = controller.nfc_values; } - - controller.nfc_state = controller.nfc_values; } bool EmulatedController::SetVibration(bool should_vibrate) { @@ -1258,7 +1229,6 @@ bool EmulatedController::SetVibration(bool should_vibrate) { vibration_value.high_amplitude = 1.0f; vibration_value.low_amplitude = 1.0f; } - return SetVibration(DeviceIndex::Left, vibration_value); } @@ -1268,7 +1238,6 @@ bool EmulatedController::SetVibration(u32 slot, Core::HID::VibrationGcErmCommand vibration_value.high_amplitude = 1.0f; vibration_value.low_amplitude = 1.0f; } - return SetVibration(DeviceIndex::Left, vibration_value); } @@ -1632,7 +1601,7 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) // Attempt to reconnect with the original type if (npad_type != original_npad_type) { Disconnect(); - const auto current_npad_type = npad_type; + const auto current_npad_type = npad_type.load(); SetNpadStyleIndex(original_npad_type); if (IsControllerSupported()) { Connect(); @@ -1650,7 +1619,7 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) // Fallback Fullkey controllers to Pro controllers if (IsControllerFullkey() && supported_style_tag.fullkey) { - LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type); + LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type.load()); SetNpadStyleIndex(NpadStyleIndex::Fullkey); Connect(); return; @@ -1658,7 +1627,7 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) // Fallback Dual joycon controllers to Pro controllers if (npad_type == NpadStyleIndex::JoyconDual && supported_style_tag.fullkey) { - LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type); + LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type.load()); SetNpadStyleIndex(NpadStyleIndex::Fullkey); Connect(); return; @@ -1666,19 +1635,16 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) // Fallback Pro controllers to Dual joycon if (npad_type == NpadStyleIndex::Fullkey && supported_style_tag.joycon_dual) { - LOG_WARNING(Service_HID, "Reconnecting controller type {} as Dual Joycons", npad_type); + LOG_WARNING(Service_HID, "Reconnecting controller type {} as Dual Joycons", npad_type.load()); SetNpadStyleIndex(NpadStyleIndex::JoyconDual); Connect(); return; } - - LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller", - npad_type); + LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller", npad_type.load()); } bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { - std::unique_lock lock{mutex}; - const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; + const auto type = is_configuring.load() && use_temporary_value ? tmp_npad_type.load() : npad_type.load(); switch (type) { case NpadStyleIndex::Fullkey: case NpadStyleIndex::GameCube: @@ -1693,39 +1659,26 @@ bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { } bool EmulatedController::IsControllerSupported(bool use_temporary_value) const { - std::unique_lock lock{mutex}; - const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; + const auto type = is_configuring.load() && use_temporary_value ? tmp_npad_type.load() : npad_type.load(); switch (type) { - case NpadStyleIndex::Fullkey: - return supported_style_tag.fullkey.As(); - case NpadStyleIndex::Handheld: - return supported_style_tag.handheld.As(); - case NpadStyleIndex::JoyconDual: - return supported_style_tag.joycon_dual.As(); - case NpadStyleIndex::JoyconLeft: - return supported_style_tag.joycon_left.As(); - case NpadStyleIndex::JoyconRight: - return supported_style_tag.joycon_right.As(); - case NpadStyleIndex::GameCube: - return supported_style_tag.gamecube.As(); - case NpadStyleIndex::Pokeball: - return supported_style_tag.palma.As(); - case NpadStyleIndex::NES: - return supported_style_tag.lark.As(); - case NpadStyleIndex::SNES: - return supported_style_tag.lucia.As(); - case NpadStyleIndex::N64: - return supported_style_tag.lagoon.As(); - case NpadStyleIndex::SegaGenesis: - return supported_style_tag.lager.As(); - default: - return false; + case NpadStyleIndex::Fullkey: return supported_style_tag.fullkey.As(); + case NpadStyleIndex::Handheld: return supported_style_tag.handheld.As(); + case NpadStyleIndex::JoyconDual: return supported_style_tag.joycon_dual.As(); + case NpadStyleIndex::JoyconLeft: return supported_style_tag.joycon_left.As(); + case NpadStyleIndex::JoyconRight: return supported_style_tag.joycon_right.As(); + case NpadStyleIndex::GameCube: return supported_style_tag.gamecube.As(); + case NpadStyleIndex::Pokeball: return supported_style_tag.palma.As(); + case NpadStyleIndex::NES: return supported_style_tag.lark.As(); + case NpadStyleIndex::SNES: return supported_style_tag.lucia.As(); + case NpadStyleIndex::N64: return supported_style_tag.lagoon.As(); + case NpadStyleIndex::SegaGenesis: return supported_style_tag.lager.As(); + default: return false; } } void EmulatedController::Connect(bool use_temporary_value) { if (!IsControllerSupported(use_temporary_value)) { - const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; + const auto type = is_configuring.load() && use_temporary_value ? tmp_npad_type.load() : npad_type.load(); LOG_ERROR(Service_HID, "Controller type {} is not supported", type); return; } @@ -1733,12 +1686,10 @@ void EmulatedController::Connect(bool use_temporary_value) { auto trigger_guard = SCOPE_GUARD { TriggerOnChange(ControllerTriggerType::Connected, !is_configuring); }; - std::unique_lock lock1{connect_mutex}, lock2{mutex}; if (is_configuring) { tmp_is_connected = true; return; } - if (is_connected) { trigger_guard.Cancel(); return; @@ -1750,12 +1701,10 @@ void EmulatedController::Disconnect() { auto trigger_guard = SCOPE_GUARD { TriggerOnChange(ControllerTriggerType::Disconnected, !is_configuring); }; - std::unique_lock lock1{connect_mutex}, lock2{mutex}; if (is_configuring) { tmp_is_connected = false; return; } - if (!is_connected) { trigger_guard.Cancel(); return; @@ -1764,19 +1713,16 @@ void EmulatedController::Disconnect() { } bool EmulatedController::IsConnected(bool get_temporary_value) const { - std::shared_lock lock{connect_mutex}; if (get_temporary_value && is_configuring) return tmp_is_connected; return is_connected; } NpadIdType EmulatedController::GetNpadIdType() const { - std::shared_lock lock{mutex}; return npad_id_type; } NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) const { - std::shared_lock lock{npad_mutex}; if (get_temporary_value && is_configuring) return tmp_npad_type; return npad_type; @@ -1786,8 +1732,6 @@ void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) { auto trigger_guard = SCOPE_GUARD { TriggerOnChange(ControllerTriggerType::Type, !is_configuring); }; - std::unique_lock lock1{mutex}, lock2{npad_mutex}; - if (is_configuring) { if (tmp_npad_type == npad_type_) { trigger_guard.Cancel(); @@ -1796,14 +1740,12 @@ void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) { tmp_npad_type = npad_type_; return; } - if (npad_type == npad_type_) { trigger_guard.Cancel(); return; } if (is_connected) { - LOG_WARNING(Service_HID, "Controller {} type changed while it's connected", - Service::HID::NpadIdTypeToIndex(npad_id_type)); + LOG_WARNING(Service_HID, "Controller {} type changed while it's connected", Service::HID::NpadIdTypeToIndex(npad_id_type)); } npad_type = npad_type_; } @@ -1832,37 +1774,30 @@ LedPattern EmulatedController::GetLedPattern() const { } ButtonValues EmulatedController::GetButtonsValues() const { - std::unique_lock lock{mutex}; return controller.button_values; } SticksValues EmulatedController::GetSticksValues() const { - std::unique_lock lock{mutex}; return controller.stick_values; } TriggerValues EmulatedController::GetTriggersValues() const { - std::unique_lock lock{mutex}; return controller.trigger_values; } ControllerMotionValues EmulatedController::GetMotionValues() const { - std::unique_lock lock{mutex}; return controller.motion_values; } ColorValues EmulatedController::GetColorsValues() const { - std::unique_lock lock{mutex}; return controller.color_values; } BatteryValues EmulatedController::GetBatteryValues() const { - std::unique_lock lock{mutex}; return controller.battery_values; } CameraValues EmulatedController::GetCameraValues() const { - std::unique_lock lock{mutex}; return controller.camera_values; } @@ -1871,72 +1806,54 @@ RingAnalogValue EmulatedController::GetRingSensorValues() const { } HomeButtonState EmulatedController::GetHomeButtons() const { - std::unique_lock lock{mutex}; - if (is_configuring) { + if (is_configuring) return {}; - } return controller.home_button_state; } CaptureButtonState EmulatedController::GetCaptureButtons() const { - std::unique_lock lock{mutex}; - if (is_configuring) { + if (is_configuring) return {}; - } return controller.capture_button_state; } NpadButtonState EmulatedController::GetNpadButtons() const { - std::unique_lock lock{mutex}; - if (is_configuring) { + if (is_configuring) return {}; - } return {controller.npad_button_state.raw & GetTurboButtonMask()}; } DebugPadButton EmulatedController::GetDebugPadButtons() const { - std::unique_lock lock{mutex}; - if (is_configuring) { + if (is_configuring) return {}; - } return controller.debug_pad_button_state; } AnalogSticks EmulatedController::GetSticks() const { - std::unique_lock lock{mutex}; - - if (is_configuring) { + if (is_configuring) return {}; - } - return controller.analog_stick_state; } NpadGcTriggerState EmulatedController::GetTriggers() const { - std::unique_lock lock{mutex}; - if (is_configuring) { + if (is_configuring) return {}; - } return controller.gc_trigger_state; } MotionState EmulatedController::GetMotions() const { - std::unique_lock lock{mutex}; return controller.motion_state; } ControllerColors EmulatedController::GetColors() const { - std::unique_lock lock{mutex}; return controller.colors_state; } BatteryLevelState EmulatedController::GetBattery() const { - std::unique_lock lock{mutex}; return controller.battery_state; } const CameraState& EmulatedController::GetCamera() const { - std::unique_lock lock{mutex}; return controller.camera_state; } @@ -1945,15 +1862,14 @@ RingSensorForce EmulatedController::GetRingSensorForce() const { } const NfcState& EmulatedController::GetNfc() const { - std::unique_lock lock{mutex}; return controller.nfc_state; } NpadColor EmulatedController::GetNpadColor(u32 color) { return { - .r = static_cast((color >> 16) & 0xFF), - .g = static_cast((color >> 8) & 0xFF), - .b = static_cast(color & 0xFF), + .r = u8((color >> 16) & 0xFF), + .g = u8((color >> 8) & 0xFF), + .b = u8(color & 0xFF), .a = 0xff, }; } diff --git a/src/hid_core/frontend/emulated_controller.h b/src/hid_core/frontend/emulated_controller.h index e4256faa3e..bee8fb8b3e 100644 --- a/src/hid_core/frontend/emulated_controller.h +++ b/src/hid_core/frontend/emulated_controller.h @@ -11,8 +11,10 @@ #include #include #include -#include #include +#include + +#include #include "common/common_types.h" #include "common/input.h" @@ -576,13 +578,7 @@ private: NpadButton GetTurboButtonMask() const; const NpadIdType npad_id_type; - NpadStyleIndex npad_type{NpadStyleIndex::None}; - NpadStyleIndex original_npad_type{NpadStyleIndex::None}; NpadStyleTag supported_style_tag{NpadStyleSet::All}; - bool is_connected{false}; - bool is_configuring{false}; - bool is_initialized{false}; - bool system_buttons_enabled{true}; f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard}; u32 turbo_button_state{0}; std::size_t nfc_handles{0}; @@ -591,9 +587,16 @@ private: std::array last_vibration_timepoint{}; std::array controller_connected{}; + // Atomically synched values + std::atomic npad_type{HID::NpadStyleIndex::None}; + std::atomic original_npad_type{HID::NpadStyleIndex::None}; // Temporary values to avoid doing changes while the controller is in configuring mode - NpadStyleIndex tmp_npad_type{NpadStyleIndex::None}; - bool tmp_is_connected{false}; + std::atomic tmp_npad_type{HID::NpadStyleIndex::None}; + std::atomic tmp_is_connected{false}; + std::atomic is_connected{false}; + std::atomic is_configuring{false}; + std::atomic is_initialized{false}; + std::atomic system_buttons_enabled{true}; ButtonParams button_params; StickParams stick_params; @@ -632,10 +635,7 @@ private: StickDevices virtual_stick_devices; ControllerMotionDevices virtual_motion_devices; - mutable std::shared_mutex mutex; - mutable std::shared_mutex callback_mutex; - mutable std::shared_mutex npad_mutex; - mutable std::shared_mutex connect_mutex; + mutable std::mutex callback_mutex; ankerl::unordered_dense::map callback_list; int last_callback_key = 0; From 975aa4e2f2128b865ec5738c2704c8d37af6a7b9 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 15 May 2026 22:06:38 +0200 Subject: [PATCH 38/58] [common] remove ptr indirection on WallClock (#3864) also devirtualizes manually since compiler doesn't do it with LTO Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3864 Reviewed-by: crueter --- src/common/CMakeLists.txt | 6 - src/common/arm64/native_clock.cpp | 87 ------- src/common/arm64/native_clock.h | 45 ---- src/common/wall_clock.cpp | 229 +++++++++++++----- src/common/wall_clock.h | 45 +++- src/common/x64/native_clock.cpp | 46 ---- src/common/x64/native_clock.h | 38 --- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 9 +- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 6 +- src/core/arm/nce/patcher.cpp | 8 +- src/core/core_timing.cpp | 155 +++++------- src/core/core_timing.h | 18 +- .../nvnflinger/buffer_queue_producer.cpp | 9 +- .../nvnflinger/buffer_queue_producer.h | 3 +- 14 files changed, 300 insertions(+), 404 deletions(-) delete mode 100644 src/common/arm64/native_clock.cpp delete mode 100644 src/common/arm64/native_clock.h delete mode 100644 src/common/x64/native_clock.cpp delete mode 100644 src/common/x64/native_clock.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index fb2bdda146..e3b662e008 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -184,8 +184,6 @@ if(ARCHITECTURE_x86_64) x64/cpu_detect.h x64/cpu_wait.cpp x64/cpu_wait.h - x64/native_clock.cpp - x64/native_clock.h x64/rdtsc.cpp x64/rdtsc.h x64/xbyak_abi.h @@ -193,10 +191,6 @@ if(ARCHITECTURE_x86_64) target_link_libraries(common PRIVATE xbyak::xbyak) endif() -if(HAS_NCE) - target_sources(common PRIVATE arm64/native_clock.cpp arm64/native_clock.h) -endif() - if(MSVC) target_compile_definitions( common diff --git a/src/common/arm64/native_clock.cpp b/src/common/arm64/native_clock.cpp deleted file mode 100644 index 76ffb74bab..0000000000 --- a/src/common/arm64/native_clock.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#ifdef ANDROID -#include -#endif -#include "common/arm64/native_clock.h" - -namespace Common::Arm64 { - -namespace { - -NativeClock::FactorType GetFixedPointFactor(u64 num, u64 den) { - return (static_cast(num) << 64) / den; -} - -u64 MultiplyHigh(u64 m, NativeClock::FactorType factor) { - return static_cast((m * factor) >> 64); -} - -} // namespace - -NativeClock::NativeClock() { - const u64 host_cntfrq = GetHostCNTFRQ(); - ns_cntfrq_factor = GetFixedPointFactor(NsRatio::den, host_cntfrq); - us_cntfrq_factor = GetFixedPointFactor(UsRatio::den, host_cntfrq); - ms_cntfrq_factor = GetFixedPointFactor(MsRatio::den, host_cntfrq); - guest_cntfrq_factor = GetFixedPointFactor(CNTFRQ, host_cntfrq); - gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq); -} - -std::chrono::nanoseconds NativeClock::GetTimeNS() const { - return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)}; -} - -std::chrono::microseconds NativeClock::GetTimeUS() const { - return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_cntfrq_factor)}; -} - -std::chrono::milliseconds NativeClock::GetTimeMS() const { - return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_cntfrq_factor)}; -} - -s64 NativeClock::GetCNTPCT() const { - return MultiplyHigh(GetUptime(), guest_cntfrq_factor); -} - -s64 NativeClock::GetGPUTick() const { - return MultiplyHigh(GetUptime(), gputick_cntfrq_factor); -} - -s64 NativeClock::GetUptime() const { - s64 cntvct_el0 = 0; - asm volatile("dsb ish\n\t" - "mrs %[cntvct_el0], cntvct_el0\n\t" - "dsb ish\n\t" - : [cntvct_el0] "=r"(cntvct_el0)); - return cntvct_el0; -} - -bool NativeClock::IsNative() const { - return true; -} - -s64 NativeClock::GetHostCNTFRQ() { - u64 cntfrq_el0 = 0; - std::string_view board{""}; -#ifdef ANDROID - char buffer[PROP_VALUE_MAX]; - int len{__system_property_get("ro.product.board", buffer)}; - board = std::string_view(buffer, static_cast(len)); -#endif - if (board == "s5e9925") { // Exynos 2200 - cntfrq_el0 = 25600000; - } else if (board == "exynos2100") { // Exynos 2100 - cntfrq_el0 = 26000000; - } else if (board == "exynos9810") { // Exynos 9810 - cntfrq_el0 = 26000000; - } else if (board == "s5e8825") { // Exynos 1280 - cntfrq_el0 = 26000000; - } else { - asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); - } - return cntfrq_el0; -} - -} // namespace Common::Arm64 diff --git a/src/common/arm64/native_clock.h b/src/common/arm64/native_clock.h deleted file mode 100644 index 94bc1882e0..0000000000 --- a/src/common/arm64/native_clock.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/wall_clock.h" - -namespace Common::Arm64 { - -class NativeClock final : public WallClock { -public: - explicit NativeClock(); - - std::chrono::nanoseconds GetTimeNS() const override; - - std::chrono::microseconds GetTimeUS() const override; - - std::chrono::milliseconds GetTimeMS() const override; - - s64 GetCNTPCT() const override; - - s64 GetGPUTick() const override; - - s64 GetUptime() const override; - - bool IsNative() const override; - - static s64 GetHostCNTFRQ(); - -public: - using FactorType = unsigned __int128; - - FactorType GetGuestCNTFRQFactor() const { - return guest_cntfrq_factor; - } - -private: - FactorType ns_cntfrq_factor; - FactorType us_cntfrq_factor; - FactorType ms_cntfrq_factor; - FactorType guest_cntfrq_factor; - FactorType gputick_cntfrq_factor; -}; - -} // namespace Common::Arm64 diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp index 4f9c240905..bff9e7b4f4 100644 --- a/src/common/wall_clock.cpp +++ b/src/common/wall_clock.cpp @@ -1,77 +1,196 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/steady_clock.h" +#include "common/uint128.h" #include "common/wall_clock.h" +#ifdef __ANDROID__ +#include +#endif #ifdef ARCHITECTURE_x86_64 #include "common/x64/cpu_detect.h" -#include "common/x64/native_clock.h" #include "common/x64/rdtsc.h" #endif -#ifdef HAS_NCE -#include "common/arm64/native_clock.h" -#endif namespace Common { -class StandardWallClock final : public WallClock { -public: - explicit StandardWallClock() {} - - std::chrono::nanoseconds GetTimeNS() const override { - return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()); - } - - std::chrono::microseconds GetTimeUS() const override { - return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()); - } - - std::chrono::milliseconds GetTimeMS() const override { - return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()); - } - - s64 GetCNTPCT() const override { - return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; - } - - s64 GetGPUTick() const override { - return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den; - } - - s64 GetUptime() const override { - return std::chrono::duration_cast( - std::chrono::steady_clock::now().time_since_epoch()) - .count(); - } - - bool IsNative() const override { - return false; - } -}; - -std::unique_ptr CreateOptimalClock() { #if defined(ARCHITECTURE_x86_64) - const auto& caps = GetCPUCaps(); +WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept + : invariant{invariant_} + , rdtsc_frequency{rdtsc_frequency_} + , ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency_)} + , us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency_)} + , ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency_)} + , cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency_)} + , gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency_)} +{} - if (caps.invariant_tsc && caps.tsc_frequency >= std::nano::den) { - return std::make_unique(caps.tsc_frequency); - } else { - // Fallback to StandardWallClock if the hardware TSC - // - Is not invariant - // - Is not more precise than 1 GHz (1ns resolution) - return std::make_unique(); - } +std::chrono::nanoseconds WallClock::GetTimeNS() const { + if (invariant) + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)}; +} + +std::chrono::microseconds WallClock::GetTimeUS() const { + if (invariant) + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_rdtsc_factor)}; +} + +std::chrono::milliseconds WallClock::GetTimeMS() const { + if (invariant) + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_rdtsc_factor)}; +} + +s64 WallClock::GetCNTPCT() const { + if (invariant) + return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; + return MultiplyHigh(GetUptime(), cntpct_rdtsc_factor); +} + +s64 WallClock::GetGPUTick() const { + if (invariant) + return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den; + return MultiplyHigh(GetUptime(), gputick_rdtsc_factor); +} + +s64 WallClock::GetUptime() const { + if (invariant) + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); + return s64(Common::X64::FencedRDTSC()); +} + +bool WallClock::IsNative() const { + if (invariant) + return false; + return true; +} #elif defined(HAS_NCE) - return std::make_unique(); +namespace { + +[[nodiscard]] WallClock::FactorType GetFixedPointFactor(u64 num, u64 den) noexcept { + return (WallClock::FactorType(num) << 64) / den; +} + +[[nodiscard]] u64 MultiplyHigh(u64 m, WallClock::FactorType factor) noexcept { + return static_cast((m * factor) >> 64); +} + +[[nodiscard]] s64 GetHostCNTFRQ() noexcept { + u64 cntfrq_el0 = 0; +#ifdef ANDROID + std::string_view board{""}; + char buffer[PROP_VALUE_MAX]; + int len{__system_property_get("ro.product.board", buffer)}; + board = std::string_view(buffer, static_cast(len)); + if (board == "s5e9925") { // Exynos 2200 + cntfrq_el0 = 25600000; + } else if (board == "exynos2100") { // Exynos 2100 + cntfrq_el0 = 26000000; + } else if (board == "exynos9810") { // Exynos 9810 + cntfrq_el0 = 26000000; + } else if (board == "s5e8825") { // Exynos 1280 + cntfrq_el0 = 26000000; + } else { + asm volatile("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); + } + return cntfrq_el0; #else - return std::make_unique(); + asm volatile("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0)); + return cntfrq_el0; +#endif +} + +} // namespace + +WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept { + const u64 host_cntfrq = std::max(GetHostCNTFRQ(), 1); + ns_cntfrq_factor = GetFixedPointFactor(NsRatio::den, host_cntfrq); + us_cntfrq_factor = GetFixedPointFactor(UsRatio::den, host_cntfrq); + ms_cntfrq_factor = GetFixedPointFactor(MsRatio::den, host_cntfrq); + guest_cntfrq_factor = GetFixedPointFactor(CNTFRQ, host_cntfrq); + gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq); +} + +std::chrono::nanoseconds WallClock::GetTimeNS() const { + return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)}; +} + +std::chrono::microseconds WallClock::GetTimeUS() const { + return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_cntfrq_factor)}; +} + +std::chrono::milliseconds WallClock::GetTimeMS() const { + return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_cntfrq_factor)}; +} + +s64 WallClock::GetCNTPCT() const { + return MultiplyHigh(GetUptime(), guest_cntfrq_factor); +} + +s64 WallClock::GetGPUTick() const { + return MultiplyHigh(GetUptime(), gputick_cntfrq_factor); +} + +s64 WallClock::GetUptime() const { + s64 cntvct_el0 = 0; + asm volatile( + "dsb ish\n\t" + "mrs %[cntvct_el0], cntvct_el0\n\t" + "dsb ish\n\t" + : [cntvct_el0] "=r"(cntvct_el0) + ); + return cntvct_el0; +} + +bool WallClock::IsNative() const { + return true; +} +#else +WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept {} + +std::chrono::nanoseconds WallClock::GetTimeNS() const { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); +} + +std::chrono::microseconds WallClock::GetTimeUS() const { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); +} + +std::chrono::milliseconds WallClock::GetTimeMS() const { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); +} + +s64 WallClock::GetCNTPCT() const { + return GetUptime() * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; +} + +s64 WallClock::GetGPUTick() const { + return GetUptime() * NsToGPUTickRatio::num / NsToGPUTickRatio::den; +} + +s64 WallClock::GetUptime() const { + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); +} + +bool WallClock::IsNative() const { + return false; +} +#endif + +WallClock CreateOptimalClock() noexcept { +#if defined(ARCHITECTURE_x86_64) + auto const& caps = GetCPUCaps(); + return WallClock(!(caps.invariant_tsc && caps.tsc_frequency >= std::nano::den), std::max(caps.tsc_frequency, 1)); +#elif defined(HAS_NCE) + return WallClock(false, 1); +#else + return WallClock(true, 1); #endif } diff --git a/src/common/wall_clock.h b/src/common/wall_clock.h index 7ad6536930..6a6d56a610 100644 --- a/src/common/wall_clock.h +++ b/src/common/wall_clock.h @@ -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: Copyright 2020 yuzu Emulator Project @@ -20,28 +20,28 @@ public: static constexpr u64 GPUTickFreq = 614'400'000; // GM20B GPU Tick Frequency = 614.4 MHz static constexpr u64 CPUTickFreq = 1'020'000'000; // T210/4 A57 CPU Tick Frequency = 1020.0 MHz - virtual ~WallClock() = default; + explicit WallClock(bool invariant, u64 rdtsc_frequency_) noexcept; /// @returns The time in nanoseconds since the construction of this clock. - virtual std::chrono::nanoseconds GetTimeNS() const = 0; + std::chrono::nanoseconds GetTimeNS() const; /// @returns The time in microseconds since the construction of this clock. - virtual std::chrono::microseconds GetTimeUS() const = 0; + std::chrono::microseconds GetTimeUS() const; /// @returns The time in milliseconds since the construction of this clock. - virtual std::chrono::milliseconds GetTimeMS() const = 0; + std::chrono::milliseconds GetTimeMS() const; /// @returns The guest CNTPCT ticks since the construction of this clock. - virtual s64 GetCNTPCT() const = 0; + s64 GetCNTPCT() const; /// @returns The guest GPU ticks since the construction of this clock. - virtual s64 GetGPUTick() const = 0; + s64 GetGPUTick() const; /// @returns The raw host timer ticks since an indeterminate epoch. - virtual s64 GetUptime() const = 0; + s64 GetUptime() const; /// @returns Whether the clock directly uses the host's hardware clock. - virtual bool IsNative() const = 0; + bool IsNative() const; static inline u64 NSToCNTPCT(u64 ns) { return ns * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den; @@ -85,8 +85,33 @@ protected: using CPUTickToUsRatio = std::ratio; using CPUTickToCNTPCTRatio = std::ratio; using CPUTickToGPUTickRatio = std::ratio; + +#if defined(ARCHITECTURE_x86_64) + bool invariant; + u64 rdtsc_frequency; + u64 ns_rdtsc_factor; + u64 us_rdtsc_factor; + u64 ms_rdtsc_factor; + u64 cntpct_rdtsc_factor; + u64 gputick_rdtsc_factor; +#elif defined(HAS_NCE) +public: + using FactorType = unsigned __int128; + + FactorType GetGuestCNTFRQFactor() const { + return guest_cntfrq_factor; + } +protected: + FactorType ns_cntfrq_factor; + FactorType us_cntfrq_factor; + FactorType ms_cntfrq_factor; + FactorType guest_cntfrq_factor; + FactorType gputick_cntfrq_factor; +#else + +#endif }; -[[nodiscard]] std::unique_ptr CreateOptimalClock(); +[[nodiscard]] WallClock CreateOptimalClock() noexcept; } // namespace Common diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp deleted file mode 100644 index d2d27fafea..0000000000 --- a/src/common/x64/native_clock.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/uint128.h" -#include "common/x64/native_clock.h" -#include "common/x64/rdtsc.h" - -namespace Common::X64 { - -NativeClock::NativeClock(u64 rdtsc_frequency_) - : rdtsc_frequency{rdtsc_frequency_}, ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, - rdtsc_frequency)}, - us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency)}, - ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency)}, - cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)}, - gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {} - -std::chrono::nanoseconds NativeClock::GetTimeNS() const { - return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)}; -} - -std::chrono::microseconds NativeClock::GetTimeUS() const { - return std::chrono::microseconds{MultiplyHigh(GetUptime(), us_rdtsc_factor)}; -} - -std::chrono::milliseconds NativeClock::GetTimeMS() const { - return std::chrono::milliseconds{MultiplyHigh(GetUptime(), ms_rdtsc_factor)}; -} - -s64 NativeClock::GetCNTPCT() const { - return MultiplyHigh(GetUptime(), cntpct_rdtsc_factor); -} - -s64 NativeClock::GetGPUTick() const { - return MultiplyHigh(GetUptime(), gputick_rdtsc_factor); -} - -s64 NativeClock::GetUptime() const { - return static_cast(FencedRDTSC()); -} - -bool NativeClock::IsNative() const { - return true; -} - -} // namespace Common::X64 diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h deleted file mode 100644 index b2629b0311..0000000000 --- a/src/common/x64/native_clock.h +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/wall_clock.h" - -namespace Common::X64 { - -class NativeClock final : public WallClock { -public: - explicit NativeClock(u64 rdtsc_frequency_); - - std::chrono::nanoseconds GetTimeNS() const override; - - std::chrono::microseconds GetTimeUS() const override; - - std::chrono::milliseconds GetTimeMS() const override; - - s64 GetCNTPCT() const override; - - s64 GetGPUTick() const override; - - s64 GetUptime() const override; - - bool IsNative() const override; - -private: - u64 rdtsc_frequency; - - u64 ns_rdtsc_factor; - u64 us_rdtsc_factor; - u64 ms_rdtsc_factor; - u64 cntpct_rdtsc_factor; - u64 gputick_rdtsc_factor; -}; - -} // namespace Common::X64 diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index c0d6ff9516..e434a31d5d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -113,8 +113,7 @@ void DynarmicCallbacks32::CallSVC(u32 swi) { } void DynarmicCallbacks32::AddTicks(u64 ticks) { - ASSERT_MSG(!m_parent.m_uses_wall_clock, "Dynarmic ticking disabled"); - + ASSERT(!m_parent.m_uses_wall_clock && "Dynarmic ticking disabled"); // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a // rough approximation of the amount of executed ticks in the system, it may be thrown off // if not all cores are doing a similar amount of work. Instead of doing this, we should @@ -123,14 +122,12 @@ void DynarmicCallbacks32::AddTicks(u64 ticks) { u64 amortized_ticks = ticks / Core::Hardware::NUM_CPU_CORES; // Always execute at least one tick. amortized_ticks = std::max(amortized_ticks, 1); - m_parent.m_system.CoreTiming().AddTicks(amortized_ticks); } u64 DynarmicCallbacks32::GetTicksRemaining() { - ASSERT_MSG(!m_parent.m_uses_wall_clock, "Dynarmic ticking disabled"); - - return std::max(m_parent.m_system.CoreTiming().GetDowncount(), 0); + ASSERT(!m_parent.m_uses_wall_clock && "Dynarmic ticking disabled"); + return std::max(m_parent.m_system.CoreTiming().downcount, 0); } bool DynarmicCallbacks32::CheckMemoryAccess(u64 addr, u64 size, Kernel::DebugWatchpointType type) { diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 63cc33d9c8..e6c7e61265 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -150,8 +150,7 @@ void DynarmicCallbacks64::CallSVC(u32 svc) { } void DynarmicCallbacks64::AddTicks(u64 ticks) { - ASSERT_MSG(!m_parent.m_uses_wall_clock, "Dynarmic ticking disabled"); - + ASSERT(!m_parent.m_uses_wall_clock && "Dynarmic ticking disabled"); // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a // rough approximation of the amount of executed ticks in the system, it may be thrown off // if not all cores are doing a similar amount of work. Instead of doing this, we should @@ -160,13 +159,12 @@ void DynarmicCallbacks64::AddTicks(u64 ticks) { u64 amortized_ticks = ticks / Core::Hardware::NUM_CPU_CORES; // Always execute at least one tick. amortized_ticks = std::max(amortized_ticks, 1); - m_parent.m_system.CoreTiming().AddTicks(amortized_ticks); } u64 DynarmicCallbacks64::GetTicksRemaining() { ASSERT(!m_parent.m_uses_wall_clock && "Dynarmic ticking disabled"); - return std::max(m_parent.m_system.CoreTiming().GetDowncount(), 0); + return std::max(m_parent.m_system.CoreTiming().downcount, 0); } u64 DynarmicCallbacks64::GetCNTPCT() { diff --git a/src/core/arm/nce/patcher.cpp b/src/core/arm/nce/patcher.cpp index ea77166645..bf72b207b9 100644 --- a/src/core/arm/nce/patcher.cpp +++ b/src/core/arm/nce/patcher.cpp @@ -3,7 +3,7 @@ #include #include -#include "common/arm64/native_clock.h" +#include "common/wall_clock.h" #include "common/alignment.h" #include "common/literals.h" #include "core/arm/nce/arm_nce.h" @@ -578,7 +578,11 @@ void Patcher::WriteMsrHandler(ModuleDestLabel module_dest, oaknut::XReg src_reg, } void Patcher::WriteCntpctHandler(ModuleDestLabel module_dest, oaknut::XReg dest_reg, oaknut::VectorCodeGenerator& cg) { - static Common::Arm64::NativeClock clock{}; +#if defined(HAS_NCE) + static Common::WallClock clock(false, 1); +#else + static Common::WallClock clock(true, 1); +#endif const auto factor = clock.GetGuestCNTFRQFactor(); const auto raw_factor = std::bit_cast>(factor); diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index b216dc2094..6738a0d73d 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -57,15 +57,51 @@ void CoreTiming::Initialize(std::function&& on_thread_init_) { Reset(); on_thread_init = std::move(on_thread_init_); event_fifo_id = 0; - shutting_down = false; cpu_ticks = 0; if (is_multicore) { - timer_thread.emplace([](CoreTiming& instance) { + timer_thread = std::jthread([this](std::stop_token stop_token) { Common::SetCurrentThreadName("HostTiming"); Common::SetCurrentThreadPriority(Common::ThreadPriority::High); - instance.on_thread_init(); - instance.ThreadLoop(); - }, std::ref(*this)); + on_thread_init(); + has_started = true; + while (!stop_token.stop_requested()) { + while (!paused && !stop_token.stop_requested()) { + paused_set = false; + if (auto const next_time = Advance(); next_time) { + // There are more events left in the queue, wait until the next event. + auto wait_time = *next_time - GetGlobalTimeNs().count(); + if (wait_time > 0) { +#ifdef _WIN32 + while (!paused && !event.IsSet() && wait_time > 0) { + wait_time = *next_time - GetGlobalTimeNs().count(); + if (wait_time >= timer_resolution_ns) { + Common::Windows::SleepForOneTick(); + } else { +#ifdef ARCHITECTURE_x86_64 + Common::X64::MicroSleep(); +#else + std::this_thread::yield(); +#endif + } + } + if (event.IsSet()) + event.Reset(); +#else + event.WaitFor(std::chrono::nanoseconds(wait_time)); +#endif + } + } else { + // Queue is empty, wait until another event is scheduled and signals us to + // continue. + wait_set = true; + event.Wait(); + } + wait_set = false; + } + paused_set = true; + pause_event.Wait(); + } + }); } } @@ -90,7 +126,7 @@ void CoreTiming::SyncPause(bool is_paused) { } Pause(is_paused); - if (timer_thread) { + if (timer_thread.joinable()) { if (!is_paused) { pause_event.Set(); } @@ -190,33 +226,22 @@ void CoreTiming::ResetTicks() { } u64 CoreTiming::GetClockTicks() const { - u64 fres; - if (is_multicore) [[likely]] { - fres = clock->GetCNTPCT(); - } else { - fres = Common::WallClock::CPUTickToCNTPCT(cpu_ticks); + u64 fres = is_multicore ? clock.GetCNTPCT() : Common::WallClock::CPUTickToCNTPCT(cpu_ticks); + if (auto const overclock = Settings::values.fast_cpu_time.GetValue(); overclock != Settings::CpuClock::Off) { + fres = u64(f64(fres) * (1.7 + 0.3 * u32(overclock))); } - - const auto overclock = Settings::values.fast_cpu_time.GetValue(); - - if (overclock != Settings::CpuClock::Off) { - fres = (u64) ((double) fres * (1.7 + 0.3 * u32(overclock))); - } - - if (Settings::values.sync_core_speed.GetValue()) { - const auto ticks = double(fres); - const auto speed_limit = double(Settings::SpeedLimit())*0.01; - return u64(ticks/speed_limit); - } else { - return fres; - } + if (::Settings::values.sync_core_speed.GetValue()) { + auto const ticks = f64(fres); + auto const speed_limit = f64(Settings::SpeedLimit()) * 0.01; + return u64(ticks / speed_limit); + } + return fres; } u64 CoreTiming::GetGPUTicks() const { - if (is_multicore) [[likely]] { - return clock->GetGPUTick(); - } - return Common::WallClock::CPUTickToGPUTick(cpu_ticks); + return is_multicore + ? clock.GetGPUTick() + : Common::WallClock::CPUTickToGPUTick(cpu_ticks); } std::optional CoreTiming::Advance() { @@ -278,75 +303,29 @@ std::optional CoreTiming::Advance() { } } -void CoreTiming::ThreadLoop() { - has_started = true; - while (!shutting_down) { - while (!paused) { - paused_set = false; - const auto next_time = Advance(); - if (next_time) { - // There are more events left in the queue, wait until the next event. - auto wait_time = *next_time - GetGlobalTimeNs().count(); - if (wait_time > 0) { -#ifdef _WIN32 - while (!paused && !event.IsSet() && wait_time > 0) { - wait_time = *next_time - GetGlobalTimeNs().count(); - if (wait_time >= timer_resolution_ns) { - Common::Windows::SleepForOneTick(); - } else { -#ifdef ARCHITECTURE_x86_64 - Common::X64::MicroSleep(); -#else - std::this_thread::yield(); -#endif - } - } - - if (event.IsSet()) { - event.Reset(); - } -#else - event.WaitFor(std::chrono::nanoseconds(wait_time)); -#endif - } - } else { - // Queue is empty, wait until another event is scheduled and signals us to - // continue. - wait_set = true; - event.Wait(); - } - wait_set = false; - } - - paused_set = true; - pause_event.Wait(); - } -} - void CoreTiming::Reset() { paused = true; - shutting_down = true; pause_event.Set(); event.Set(); - if (timer_thread) { - timer_thread->join(); + if (timer_thread.joinable()) { + timer_thread.request_stop(); + timer_thread.join(); } - timer_thread.reset(); has_started = false; } -std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const { - if (is_multicore) [[likely]] { - return clock->GetTimeNS(); - } - return std::chrono::nanoseconds{Common::WallClock::CPUTickToNS(cpu_ticks)}; +/// @brief Returns current time in nanoseconds. +std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const noexcept { + return is_multicore + ? clock.GetTimeNS() + : std::chrono::nanoseconds{Common::WallClock::CPUTickToNS(cpu_ticks)}; } -std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const { - if (is_multicore) [[likely]] { - return clock->GetTimeUS(); - } - return std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)}; +/// @brief Returns current time in microseconds. +std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const noexcept { + return is_multicore + ? clock.GetTimeUS() + : std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)}; } #ifdef _WIN32 diff --git a/src/core/core_timing.h b/src/core/core_timing.h index ae9f56d519..5967c83b57 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -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: Copyright 2020 yuzu Emulator Project @@ -118,7 +118,7 @@ public: void Idle(); - s64 GetDowncount() const { + s64 GetDowncount() const noexcept { return downcount; } @@ -128,11 +128,8 @@ public: /// Returns the current GPU tick value. u64 GetGPUTicks() const; - /// Returns current time in microseconds. - std::chrono::microseconds GetGlobalTimeUs() const; - - /// Returns current time in nanoseconds. - std::chrono::nanoseconds GetGlobalTimeNs() const; + [[nodiscard]] std::chrono::microseconds GetGlobalTimeUs() const noexcept; + [[nodiscard]] std::chrono::nanoseconds GetGlobalTimeNs() const noexcept; /// Checks for events manually and returns time in nanoseconds for next event, threadsafe. std::optional Advance(); @@ -141,13 +138,11 @@ public: void SetTimerResolutionNs(std::chrono::nanoseconds ns); #endif -private: struct Event; - void ThreadLoop(); void Reset(); - std::unique_ptr clock; + Common::WallClock clock; s64 global_timer = 0; @@ -165,11 +160,10 @@ private: Common::Event pause_event{}; mutable std::mutex basic_lock; std::mutex advance_lock; - std::optional timer_thread; + std::jthread timer_thread; std::atomic paused{}; std::atomic paused_set{}; std::atomic wait_set{}; - std::atomic shutting_down{}; std::atomic has_started{}; std::function on_thread_init{}; diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index 436b0f4b05..bb0433e1d0 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -26,8 +26,11 @@ namespace Service::android { BufferQueueProducer::BufferQueueProducer(Service::KernelHelpers::ServiceContext& service_context_, std::shared_ptr buffer_queue_core_, Service::Nvidia::NvCore::NvMap& nvmap_) - : service_context{service_context_}, core{std::move(buffer_queue_core_)}, slots(core->slots), - clock{Common::CreateOptimalClock()}, nvmap(nvmap_) { + : service_context{service_context_}, core{std::move(buffer_queue_core_)} + , slots(core->slots) + , clock{Common::CreateOptimalClock()} + , nvmap(nvmap_) +{ buffer_wait_event = service_context.CreateEvent("BufferQueue:WaitEvent"); } @@ -485,7 +488,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, slots[slot].buffer_state = BufferState::Queued; slots[slot].frame_number = core->frame_counter; slots[slot].queue_time = timestamp; - slots[slot].presentation_time = clock->GetTimeNS().count(); + slots[slot].presentation_time = clock.GetTimeNS().count(); slots[slot].fence = fence; item.slot = slot; diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h index 06cb49cbad..51c0801a0a 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h @@ -89,8 +89,7 @@ private: s32 next_callback_ticket{}; s32 current_callback_ticket{}; std::condition_variable_any callback_condition; - std::unique_ptr clock; - + Common::WallClock clock; Service::Nvidia::NvCore::NvMap& nvmap; }; From 413c7543ba25407f79226ba5e3f2f88d0ae63501 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 15 May 2026 22:07:03 +0200 Subject: [PATCH 39/58] [hle] inline HLE cmif request to not allocate on heap stuff (#3605) so basically each construction of HLEContext and whatever would result in a heap allocation (atleast 1) so what if instead of that we did a memset() at ctor time and we avoided heap allocations altogether? reminder that std::vector<> CAN do small object optimisation but it's not guaranteed Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3605 Reviewed-by: crueter --- src/core/hle/ipc.h | 13 ++++++++ src/core/hle/service/hle_ipc.cpp | 18 ++++------- src/core/hle/service/hle_ipc.h | 52 ++++++++++++++++---------------- src/core/reporter.cpp | 6 ++-- 4 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h index 416da15ecb..9cd2908823 100644 --- a/src/core/hle/ipc.h +++ b/src/core/hle/ipc.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -13,6 +16,16 @@ namespace IPC { /// Size of the command buffer area, in 32-bit words. constexpr std::size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32); +/// Must match bitfields +constexpr std::size_t MAX_BUFFER_DESCRIPTORS = 16; +constexpr std::size_t MAX_INCOMING_MOVE_HANDLERS = 16; +constexpr std::size_t MAX_INCOMING_COPY_HANDLERS = 16; + +/// Doesn't need to match bitfields but usually not big enough +constexpr std::size_t MAX_OUTGOING_COPY_OBJECTS = 16; +constexpr std::size_t MAX_OUTGOING_MOVE_OBJECTS = 16; +constexpr std::size_t MAX_OUTGOING_DOMAIN_OBJECTS = 16; + enum class ControlCommand : u32 { ConvertSessionToDomain = 0, ConvertDomainToSession = 1, diff --git a/src/core/hle/service/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp index 8569d2bad8..8db8f8538c 100644 --- a/src/core/hle/service/hle_ipc.cpp +++ b/src/core/hle/service/hle_ipc.cpp @@ -128,10 +128,12 @@ Result SessionRequestManager::HandleDomainSyncRequest(Kernel::KServerSession* se return ResultSuccess; } -HLERequestContext::HLERequestContext(Kernel::KernelCore& kernel_, Core::Memory::Memory& memory_, - Kernel::KServerSession* server_session_, - Kernel::KThread* thread_) - : server_session(server_session_), thread(thread_), kernel{kernel_}, memory{memory_} { +HLERequestContext::HLERequestContext(Kernel::KernelCore& kernel_, Core::Memory::Memory& memory_, Kernel::KServerSession* server_session_, Kernel::KThread* thread_) + : server_session(server_session_) + , thread(thread_) + , kernel{kernel_} + , memory{memory_} +{ cmd_buf[0] = 0; } @@ -155,9 +157,6 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { } if (incoming) { // Populate the object lists with the data in the IPC request. - incoming_copy_handles.reserve(handle_descriptor_header->num_handles_to_copy); - incoming_move_handles.reserve(handle_descriptor_header->num_handles_to_move); - for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) { incoming_copy_handles.push_back(rp.Pop()); } @@ -172,11 +171,6 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { } } - buffer_x_descriptors.reserve(command_header->num_buf_x_descriptors); - buffer_a_descriptors.reserve(command_header->num_buf_a_descriptors); - buffer_b_descriptors.reserve(command_header->num_buf_b_descriptors); - buffer_w_descriptors.reserve(command_header->num_buf_w_descriptors); - for (u32 i = 0; i < command_header->num_buf_x_descriptors; ++i) { buffer_x_descriptors.push_back(rp.PopRaw()); } diff --git a/src/core/hle/service/hle_ipc.h b/src/core/hle/service/hle_ipc.h index c2e0e5e8c4..ec8185a09e 100644 --- a/src/core/hle/service/hle_ipc.h +++ b/src/core/hle/service/hle_ipc.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -11,6 +14,7 @@ #include #include #include +#include #include "common/assert.h" #include "common/common_types.h" @@ -181,8 +185,7 @@ private: */ class HLERequestContext { public: - explicit HLERequestContext(Kernel::KernelCore& kernel, Core::Memory::Memory& memory, - Kernel::KServerSession* session, Kernel::KThread* thread); + explicit HLERequestContext(Kernel::KernelCore& kernel, Core::Memory::Memory& memory, Kernel::KServerSession* session, Kernel::KThread* thread); ~HLERequestContext(); /// Returns a pointer to the IPC command buffer for this request. @@ -233,19 +236,19 @@ public: return data_payload_offset; } - [[nodiscard]] const std::vector& BufferDescriptorX() const { + [[nodiscard]] const boost::container::static_vector& BufferDescriptorX() const { return buffer_x_descriptors; } - [[nodiscard]] const std::vector& BufferDescriptorA() const { + [[nodiscard]] const boost::container::static_vector& BufferDescriptorA() const { return buffer_a_descriptors; } - [[nodiscard]] const std::vector& BufferDescriptorB() const { + [[nodiscard]] const boost::container::static_vector& BufferDescriptorB() const { return buffer_b_descriptors; } - [[nodiscard]] const std::vector& BufferDescriptorC() const { + [[nodiscard]] const boost::container::static_vector& BufferDescriptorC() const { return buffer_c_descriptors; } @@ -399,38 +402,35 @@ private: Kernel::KHandleTable* client_handle_table{}; Kernel::KThread* thread{}; - std::vector incoming_move_handles; - std::vector incoming_copy_handles; + boost::container::static_vector buffer_x_descriptors; + boost::container::static_vector buffer_a_descriptors; + boost::container::static_vector buffer_b_descriptors; + boost::container::static_vector buffer_w_descriptors; + boost::container::static_vector buffer_c_descriptors; + boost::container::static_vector incoming_move_handles; + boost::container::static_vector incoming_copy_handles; + boost::container::static_vector outgoing_move_objects; + boost::container::static_vector outgoing_copy_objects; + boost::container::static_vector outgoing_domain_objects; - std::vector outgoing_move_objects; - std::vector outgoing_copy_objects; - std::vector outgoing_domain_objects; + mutable std::array, 3> read_buffer_data_a{}; + mutable std::array, 3> read_buffer_data_x{}; std::optional command_header; std::optional handle_descriptor_header; std::optional data_payload_header; std::optional domain_message_header; - std::vector buffer_x_descriptors; - std::vector buffer_a_descriptors; - std::vector buffer_b_descriptors; - std::vector buffer_w_descriptors; - std::vector buffer_c_descriptors; + std::weak_ptr manager{}; + Kernel::KernelCore& kernel; + Core::Memory::Memory& memory; - u32_le command{}; u64 pid{}; + u32_le command{}; u32 write_size{}; u32 data_payload_offset{}; u32 handles_offset{}; u32 domain_offset{}; - - std::weak_ptr manager{}; - bool is_deferred{false}; - - Kernel::KernelCore& kernel; - Core::Memory::Memory& memory; - - mutable std::array, 3> read_buffer_data_a{}; - mutable std::array, 3> read_buffer_data_x{}; + bool is_deferred = false; }; } // namespace Service diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 1723636811..2a5212fed8 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -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: Copyright 2019 yuzu Emulator Project @@ -20,6 +20,7 @@ #include "common/settings.h" #include "core/arm/arm_interface.h" #include "core/core.h" +#include "core/hle/ipc.h" #include "core/hle/kernel/k_page_table.h" #include "core/hle/kernel/k_process.h" #include "core/hle/result.h" @@ -124,8 +125,7 @@ json GetFullDataAuto(const std::string& timestamp, u64 title_id, Core::System& s } template -json GetHLEBufferDescriptorData(const std::vector& buffer, - Core::Memory::Memory& memory) { +json GetHLEBufferDescriptorData(const boost::container::static_vector& buffer, Core::Memory::Memory& memory) { auto buffer_out = json::array(); for (const auto& desc : buffer) { auto entry = json{ From 2f0f8a979c88b1ded8b5cce9f9bee1a59bb2508c Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 15 May 2026 22:07:45 +0200 Subject: [PATCH 40/58] [dynarmic, macroHLE] Use faster ankerl for xbyak maps (#3716) the nominal std::unordered_map<> isn't enough to warrant it's continued usage in xbyak internal structures, thus using ankerl should greatly remove a lot of indirection/stdc++ specific overhead from the usually poorly performant std::unordered_map Both dynarmic and macroHLE should benefit greatly from a less-stupid unordered_dense This should speedup both CPU and shader compilation latency (NOT BY A GREAT MARGIN) just enough to make loading zones in ToTK less horrific Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3716 Reviewed-by: crueter --- src/common/CMakeLists.txt | 3 +- src/common/x64/{xbyak_abi.h => xbyak.h} | 72 +++++++++++++++++-- src/common/x64/xbyak_util.h | 46 ------------ .../src/dynarmic/backend/x64/a64_emit_x64.cpp | 4 +- src/dynarmic/src/dynarmic/backend/x64/abi.cpp | 10 +-- .../dynarmic/backend/x64/constant_pool.cpp | 10 +-- .../src/dynarmic/backend/x64/hostloc.h | 2 - src/dynarmic/src/dynarmic/backend/x64/xbyak.h | 14 ++-- .../src/dynarmic/common/fp/op/FPToFixed.cpp | 6 +- src/dynarmic/tests/x64_cpu_info.cpp | 5 +- src/video_core/macro.cpp | 16 +---- 11 files changed, 93 insertions(+), 95 deletions(-) rename src/common/x64/{xbyak_abi.h => xbyak.h} (75%) delete mode 100644 src/common/x64/xbyak_util.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index e3b662e008..c5740bfb83 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -186,8 +186,7 @@ if(ARCHITECTURE_x86_64) x64/cpu_wait.h x64/rdtsc.cpp x64/rdtsc.h - x64/xbyak_abi.h - x64/xbyak_util.h) + x64/xbyak.h) target_link_libraries(common PRIVATE xbyak::xbyak) endif() diff --git a/src/common/x64/xbyak_abi.h b/src/common/x64/xbyak.h similarity index 75% rename from src/common/x64/xbyak_abi.h rename to src/common/x64/xbyak.h index 8aea5db583..5ee12576e9 100644 --- a/src/common/x64/xbyak_abi.h +++ b/src/common/x64/xbyak.h @@ -1,13 +1,37 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once +#include #include #include -#include #include "common/assert.h" +// xbyak hates human beings +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wshadow" +#endif +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wconversion" +#pragma clang diagnostic ignored "-Wshadow" +#endif + +// You must ensure this matches with src/common/x64/xbyak.h on root dir +#include +#include +#define XBYAK_STD_UNORDERED_SET ankerl::unordered_dense::set +#define XBYAK_STD_UNORDERED_MAP ankerl::unordered_dense::map +#define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap +#include +#include + +#include + namespace Common::X64 { constexpr size_t RegToIndex(const Xbyak::Reg& reg) { @@ -174,12 +198,13 @@ inline ABIFrameInfo ABI_CalculateFrameSize(std::bitset<32> regs, size_t rsp_alig rsp_alignment -= subtraction; subtraction += rsp_alignment & 0xF; - return ABIFrameInfo{static_cast(subtraction), - static_cast(subtraction - xmm_base_subtraction)}; + return ABIFrameInfo{ + s32(subtraction), + s32(subtraction - xmm_base_subtraction) + }; } -inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bitset<32> regs, - size_t rsp_alignment, size_t needed_frame_size = 0) { +inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bitset<32> regs, size_t rsp_alignment, size_t needed_frame_size = 0) { auto frame_info = ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size); for (size_t i = 0; i < regs.size(); ++i) { @@ -202,8 +227,7 @@ inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::b return ABI_SHADOW_SPACE; } -inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bitset<32> regs, - size_t rsp_alignment, size_t needed_frame_size = 0) { +inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bitset<32> regs, size_t rsp_alignment, size_t needed_frame_size = 0) { auto frame_info = ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size); for (size_t i = 0; i < regs.size(); ++i) { @@ -226,4 +250,38 @@ inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bits } } +// Constants for use with cmpps/cmpss +enum { + CMP_EQ = 0, + CMP_LT = 1, + CMP_LE = 2, + CMP_UNORD = 3, + CMP_NEQ = 4, + CMP_NLT = 5, + CMP_NLE = 6, + CMP_ORD = 7, +}; + +constexpr bool IsWithin2G(uintptr_t ref, uintptr_t target) { + const u64 distance = target - (ref + 5); + return !(distance >= 0x8000'0000ULL && distance <= ~0x8000'0000ULL); +} + +inline bool IsWithin2G(const Xbyak::CodeGenerator& code, uintptr_t target) { + return IsWithin2G(reinterpret_cast(code.getCurr()), target); +} + +template +inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) { + static_assert(std::is_pointer_v, "Argument must be a (function) pointer."); + size_t addr = reinterpret_cast(f); + if (IsWithin2G(code, addr)) { + code.call(f); + } else { + // ABI_RETURN is a safe temp register to use before a call + code.mov(ABI_RETURN, addr); + code.call(ABI_RETURN); + } +} + } // namespace Common::X64 diff --git a/src/common/x64/xbyak_util.h b/src/common/x64/xbyak_util.h deleted file mode 100644 index 250e5cddb9..0000000000 --- a/src/common/x64/xbyak_util.h +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-FileCopyrightText: 2016 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include "common/x64/xbyak_abi.h" - -namespace Common::X64 { - -// Constants for use with cmpps/cmpss -enum { - CMP_EQ = 0, - CMP_LT = 1, - CMP_LE = 2, - CMP_UNORD = 3, - CMP_NEQ = 4, - CMP_NLT = 5, - CMP_NLE = 6, - CMP_ORD = 7, -}; - -constexpr bool IsWithin2G(uintptr_t ref, uintptr_t target) { - const u64 distance = target - (ref + 5); - return !(distance >= 0x8000'0000ULL && distance <= ~0x8000'0000ULL); -} - -inline bool IsWithin2G(const Xbyak::CodeGenerator& code, uintptr_t target) { - return IsWithin2G(reinterpret_cast(code.getCurr()), target); -} - -template -inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) { - static_assert(std::is_pointer_v, "Argument must be a (function) pointer."); - size_t addr = reinterpret_cast(f); - if (IsWithin2G(code, addr)) { - code.call(f); - } else { - // ABI_RETURN is a safe temp register to use before a call - code.mov(ABI_RETURN, addr); - code.call(ABI_RETURN); - } -} - -} // namespace Common::X64 diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp index cf9dab4034..53381aa1df 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp @@ -224,7 +224,7 @@ void A64EmitX64::GenTerminalHandlers() { terminal_handler_fast_dispatch_hint = code.getCurr(); calculate_location_descriptor(); code.L(rsb_cache_miss); - code.mov(r8, reinterpret_cast(fast_dispatch_table.data())); + code.mov(r8, u64(fast_dispatch_table.data())); //code.mov(r12, qword[code.ABI_JIT_PTR + offsetof(A64JitState, pc)]); code.mov(r12, rbx); if (code.HasHostFeature(HostFeature::SSE42)) { @@ -244,7 +244,7 @@ void A64EmitX64::GenTerminalHandlers() { code.align(); fast_dispatch_table_lookup = code.getCurr(); - code.mov(code.ABI_PARAM2, reinterpret_cast(fast_dispatch_table.data())); + code.mov(code.ABI_PARAM2, u64(fast_dispatch_table.data())); if (code.HasHostFeature(HostFeature::SSE42)) { code.crc32(code.ABI_PARAM1, code.ABI_PARAM2); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp index 5d2ee735f3..59ecc974f7 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp @@ -26,7 +26,7 @@ struct FrameInfo { }; static_assert(ABI_SHADOW_SPACE <= 32); -static FrameInfo CalculateFrameInfo(const size_t num_gprs, const size_t num_xmms, size_t frame_size) { +static FrameInfo CalculateFrameInfo(const size_t num_gprs, const size_t num_xmms, size_t frame_size) noexcept { // We are initially 8 byte aligned because the return value is pushed onto an aligned stack after a call. const size_t rsp_alignment = (num_gprs % 2 == 0) ? 8 : 0; const size_t total_xmm_size = num_xmms * XMM_SIZE; @@ -40,7 +40,7 @@ static FrameInfo CalculateFrameInfo(const size_t num_gprs, const size_t num_xmms }; } -void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> const& regs) { +static void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> regs) noexcept { using namespace Xbyak::util; const size_t num_gprs = (ABI_ALL_GPRS & regs).count(); @@ -65,7 +65,7 @@ void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, } } -void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> const& regs) { +static void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> regs) noexcept { using namespace Xbyak::util; const size_t num_gprs = (ABI_ALL_GPRS & regs).count(); @@ -107,13 +107,13 @@ void ABI_PopCallerSaveRegistersAndAdjustStack(BlockOfCode& code, const std::size // Windows ABI registers are not in the same allocation algorithm as unix's void ABI_PushCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, const HostLoc exception) { - std::bitset<32> regs = ABI_ALL_CALLER_SAVE; + auto regs = ABI_ALL_CALLER_SAVE; regs.reset(size_t(exception)); ABI_PushRegistersAndAdjustStack(code, 0, regs); } void ABI_PopCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, const HostLoc exception) { - std::bitset<32> regs = ABI_ALL_CALLER_SAVE; + auto regs = ABI_ALL_CALLER_SAVE; regs.reset(size_t(exception)); ABI_PopRegistersAndAdjustStack(code, 0, regs); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp index 127149a29e..e2b8c94148 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp @@ -6,23 +6,23 @@ * SPDX-License-Identifier: 0BSD */ -#include "dynarmic/backend/x64/constant_pool.h" - #include #include "common/assert.h" #include "dynarmic/backend/x64/block_of_code.h" +#include "dynarmic/backend/x64/constant_pool.h" namespace Dynarmic::Backend::X64 { ConstantPool::ConstantPool(BlockOfCode& code, size_t size) - : code(code), insertion_point(0) { + : code(code) + , insertion_point(0) +{ code.EnsureMemoryCommitted(align_size + size); code.int3(); code.align(align_size); - pool = std::span( - reinterpret_cast(code.AllocateFromCodeSpace(size)), size / align_size); + pool = std::span(reinterpret_cast(code.AllocateFromCodeSpace(size)), size / align_size); } Xbyak::Address ConstantPool::GetConstant(const Xbyak::AddressFrame& frame, u64 lower, u64 upper) { diff --git a/src/dynarmic/src/dynarmic/backend/x64/hostloc.h b/src/dynarmic/src/dynarmic/backend/x64/hostloc.h index 7191a0ceba..d62090d612 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/hostloc.h +++ b/src/dynarmic/src/dynarmic/backend/x64/hostloc.h @@ -8,8 +8,6 @@ #pragma once #include -#include - #include "common/assert.h" #include "common/common_types.h" #include "dynarmic/backend/x64/xbyak.h" diff --git a/src/dynarmic/src/dynarmic/backend/x64/xbyak.h b/src/dynarmic/src/dynarmic/backend/x64/xbyak.h index ee74794fb4..38401678e6 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/xbyak.h +++ b/src/dynarmic/src/dynarmic/backend/x64/xbyak.h @@ -3,13 +3,11 @@ #pragma once -#include -#include - -// TODO: Defining this crashes e v e r y t h i n g -// #define XBYAK_STD_UNORDERED_SET ankerl::unordered_dense::set -// #define XBYAK_STD_UNORDERED_MAP ankerl::unordered_dense::map -// #define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap - +// You must ensure this matches with src/common/x64/xbyak.h on root dir +#include +#include +#define XBYAK_STD_UNORDERED_SET ankerl::unordered_dense::set +#define XBYAK_STD_UNORDERED_MAP ankerl::unordered_dense::map +#define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap #include #include diff --git a/src/dynarmic/src/dynarmic/common/fp/op/FPToFixed.cpp b/src/dynarmic/src/dynarmic/common/fp/op/FPToFixed.cpp index d920f2d900..7c322050c3 100644 --- a/src/dynarmic/src/dynarmic/common/fp/op/FPToFixed.cpp +++ b/src/dynarmic/src/dynarmic/common/fp/op/FPToFixed.cpp @@ -78,7 +78,7 @@ u64 FPToFixed(size_t ibits, FPT op, size_t fbits, bool unsigned_, FPCR fpcr, Rou } // Detect Overflow - const int min_exponent_for_overflow = static_cast(ibits) - static_cast(mcl::bit::highest_set_bit(value.mantissa + (round_up ? Safe::LogicalShiftRight(1, exponent) : 0))) - (unsigned_ ? 0 : 1); + const int min_exponent_for_overflow = int(ibits) - int(mcl::bit::highest_set_bit(value.mantissa + (round_up ? Safe::LogicalShiftRight(1, exponent) : 0))) - (unsigned_ ? 0 : 1); if (exponent >= min_exponent_for_overflow) { // Positive overflow if (unsigned_ || !sign) { @@ -87,10 +87,10 @@ u64 FPToFixed(size_t ibits, FPT op, size_t fbits, bool unsigned_, FPCR fpcr, Rou } // Negative overflow - const u64 min_value = Safe::Negate(static_cast(1) << (ibits - 1)); + const u64 min_value = Safe::Negate(u64(1) << (ibits - 1)); if (!(exponent == min_exponent_for_overflow && int_result == min_value)) { FPProcessException(FPExc::InvalidOp, fpcr, fpsr); - return static_cast(1) << (ibits - 1); + return u64(1) << (ibits - 1); } } diff --git a/src/dynarmic/tests/x64_cpu_info.cpp b/src/dynarmic/tests/x64_cpu_info.cpp index 8e67f0fc39..a33d8c013f 100644 --- a/src/dynarmic/tests/x64_cpu_info.cpp +++ b/src/dynarmic/tests/x64_cpu_info.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* This file is part of the dynarmic project. * Copyright (c) 2020 MerryMage * SPDX-License-Identifier: 0BSD @@ -11,7 +14,7 @@ #include #include -#include +#include "dynarmic/backend/x64/xbyak.h" TEST_CASE("Host CPU supports", "[a64]") { using Cpu = Xbyak::util::Cpu; diff --git a/src/video_core/macro.cpp b/src/video_core/macro.cpp index 606162ba8d..dbf011860e 100644 --- a/src/video_core/macro.cpp +++ b/src/video_core/macro.cpp @@ -11,17 +11,9 @@ #include #include + #ifdef ARCHITECTURE_x86_64 -// xbyak hates human beings -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wshadow" -#endif -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wshadow" -#endif -#include +#include "common/x64/xbyak.h" #endif #include "common/assert.h" @@ -39,10 +31,6 @@ #include "common/assert.h" #include "common/bit_field.h" #include "common/logging.h" -#ifdef ARCHITECTURE_x86_64 -#include "common/x64/xbyak_abi.h" -#include "common/x64/xbyak_util.h" -#endif #include "video_core/engines/maxwell_3d.h" namespace Tegra { From 4d49341918981a782395fe379a8e6846e1fd11b2 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 15 May 2026 22:08:09 +0200 Subject: [PATCH 41/58] [vk, opengl] recognize and use ETC2 (if available) textures natively (#3237) this makes it so VK and OGL backends map the NVIDIA's ETC2 into VK_FORMAT_ETC-whatever and GL_ETC-whatever remaps, instead of using the default fallback for AR8G8B8. in short, just make the ETC2 textures be submitted as ETC2 instead of being submit as A8R8G8B8. Signed-off-by: lizzie lizzie@eden-emu.dev Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3237 Reviewed-by: Ghost <> Reviewed-by: crueter --- .../renderer_vulkan/maxwell_to_vk.cpp | 11 +- src/video_core/surface.cpp | 19 +- src/video_core/surface.h | 9 +- .../texture_cache/format_lookup_table.cpp | 14 ++ src/video_core/texture_cache/formatter.h | 210 +----------------- src/video_core/vulkan_common/vulkan_device.h | 5 + 6 files changed, 60 insertions(+), 208 deletions(-) diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 930f06daf6..77ef8bf7bc 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -217,6 +217,12 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 0, ASTC_2D_6X5_UNORM) \ SURFACE_FORMAT_ELEM(VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 0, ASTC_2D_6X5_SRGB) \ SURFACE_FORMAT_ELEM(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 0, E5B9G9R9_FLOAT) \ + SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, 0, ETC2_RGB_UNORM) \ + SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, 0, ETC2_RGBA_UNORM) \ + SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, 0, ETC2_RGB_PTA_UNORM) \ + SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, 0, ETC2_RGB_SRGB) \ + SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, 0, ETC2_RGBA_SRGB) \ + SURFACE_FORMAT_ELEM(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, 0, ETC2_RGB_PTA_SRGB) \ /* Depth formats */ \ SURFACE_FORMAT_ELEM(VK_FORMAT_D32_SFLOAT, usage_attachable, D32_FLOAT) \ SURFACE_FORMAT_ELEM(VK_FORMAT_D16_UNORM, usage_attachable, D16_UNORM) \ @@ -253,8 +259,8 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with break; } } - // Transcode on hardware that doesn't support BCn natively if (!device.IsOptimalBcnSupported() && VideoCore::Surface::IsPixelFormatBCn(pixel_format)) { + // Transcode on hardware that doesn't support BCn natively if (pixel_format == PixelFormat::BC4_SNORM) { tuple.format = VK_FORMAT_R8_SNORM; } else if (pixel_format == PixelFormat::BC4_UNORM) { @@ -270,6 +276,9 @@ FormatInfo SurfaceFormat(const Device& device, FormatType format_type, bool with } else { tuple.format = VK_FORMAT_A8B8G8R8_UNORM_PACK32; } + } else if (!device.IsOptimalEtc2Supported() && VideoCore::Surface::IsPixelFormatETC2(pixel_format)) { + // Transcode on hardware that doesn't support ETC2 natively + tuple.format = is_srgb ? VK_FORMAT_A8B8G8R8_SRGB_PACK32 : VK_FORMAT_A8B8G8R8_UNORM_PACK32; } bool const attachable = (tuple.usage & usage_attachable) != 0; bool const storage = (tuple.usage & usage_storage) != 0; diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 1998849e84..69c1720943 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -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: 2014 Citra Emulator Project @@ -336,6 +336,20 @@ bool IsPixelFormatBCn(PixelFormat format) { } } +bool IsPixelFormatETC2(PixelFormat format) { + switch (format) { + case PixelFormat::ETC2_RGB_UNORM: + case PixelFormat::ETC2_RGBA_UNORM: + case PixelFormat::ETC2_RGB_PTA_UNORM: + case PixelFormat::ETC2_RGB_SRGB: + case PixelFormat::ETC2_RGBA_SRGB: + case PixelFormat::ETC2_RGB_PTA_SRGB: + return true; + default: + return false; + } +} + bool IsPixelFormatSRGB(PixelFormat format) { switch (format) { case PixelFormat::A8B8G8R8_SRGB: @@ -344,6 +358,9 @@ bool IsPixelFormatSRGB(PixelFormat format) { case PixelFormat::BC2_SRGB: case PixelFormat::BC3_SRGB: case PixelFormat::BC7_SRGB: + case PixelFormat::ETC2_RGB_SRGB: + case PixelFormat::ETC2_RGBA_SRGB: + case PixelFormat::ETC2_RGB_PTA_SRGB: case PixelFormat::ASTC_2D_4X4_SRGB: case PixelFormat::ASTC_2D_8X8_SRGB: case PixelFormat::ASTC_2D_8X5_SRGB: diff --git a/src/video_core/surface.h b/src/video_core/surface.h index a97bcb39b5..c659a977c1 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -111,6 +111,12 @@ namespace VideoCore::Surface { PIXEL_FORMAT_ELEM(ASTC_2D_6X5_UNORM, 6, 5, 128) \ PIXEL_FORMAT_ELEM(ASTC_2D_6X5_SRGB, 6, 5, 128) \ PIXEL_FORMAT_ELEM(E5B9G9R9_FLOAT, 1, 1, 32) \ + PIXEL_FORMAT_ELEM(ETC2_RGB_UNORM, 4, 4, 64) \ + PIXEL_FORMAT_ELEM(ETC2_RGBA_UNORM, 4, 4, 128) \ + PIXEL_FORMAT_ELEM(ETC2_RGB_PTA_UNORM, 4, 4, 64) \ + PIXEL_FORMAT_ELEM(ETC2_RGB_SRGB, 4, 4, 64) \ + PIXEL_FORMAT_ELEM(ETC2_RGBA_SRGB, 4, 4, 128) \ + PIXEL_FORMAT_ELEM(ETC2_RGB_PTA_SRGB, 4, 4, 64) \ /* Depth formats */ \ PIXEL_FORMAT_ELEM(D32_FLOAT, 1, 1, 32) \ PIXEL_FORMAT_ELEM(D16_UNORM, 1, 1, 16) \ @@ -181,8 +187,6 @@ constexpr u32 BitsPerBlock(PixelFormat format) noexcept { } } -#undef PIXEL_FORMAT_LIST - /// Returns the sizer in bytes of the specified pixel format constexpr u32 BytesPerBlock(PixelFormat pixel_format) { return BitsPerBlock(pixel_format) / CHAR_BIT; @@ -198,6 +202,7 @@ SurfaceType GetFormatType(PixelFormat pixel_format); bool HasAlpha(PixelFormat pixel_format); bool IsPixelFormatASTC(PixelFormat format); bool IsPixelFormatBCn(PixelFormat format); +bool IsPixelFormatETC2(PixelFormat format); bool IsPixelFormatSRGB(PixelFormat format); bool IsPixelFormatInteger(PixelFormat format); bool IsPixelFormatSignedInteger(PixelFormat format); diff --git a/src/video_core/texture_cache/format_lookup_table.cpp b/src/video_core/texture_cache/format_lookup_table.cpp index a9e03b375d..ea68a1c063 100644 --- a/src/video_core/texture_cache/format_lookup_table.cpp +++ b/src/video_core/texture_cache/format_lookup_table.cpp @@ -191,6 +191,20 @@ PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red, return PixelFormat::BC6H_SFLOAT; case Hash(TextureFormat::BC6H_U16, FLOAT): return PixelFormat::BC6H_UFLOAT; + /* ETC2 */ + case Hash(TextureFormat::ETC2_RGB, UNORM, LINEAR): + return PixelFormat::ETC2_RGB_UNORM; + case Hash(TextureFormat::ETC2_RGB_PTA, UNORM, LINEAR): + return PixelFormat::ETC2_RGB_PTA_UNORM; + case Hash(TextureFormat::ETC2_RGBA, UNORM, LINEAR): + return PixelFormat::ETC2_RGBA_UNORM; + case Hash(TextureFormat::ETC2_RGB, UNORM, SRGB): + return PixelFormat::ETC2_RGB_SRGB; + case Hash(TextureFormat::ETC2_RGB_PTA, UNORM, SRGB): + return PixelFormat::ETC2_RGB_PTA_SRGB; + case Hash(TextureFormat::ETC2_RGBA, UNORM, SRGB): + return PixelFormat::ETC2_RGBA_SRGB; + /* ASTC */ case Hash(TextureFormat::ASTC_2D_4X4, UNORM, LINEAR): return PixelFormat::ASTC_2D_4X4_UNORM; case Hash(TextureFormat::ASTC_2D_4X4, UNORM, SRGB): diff --git a/src/video_core/texture_cache/formatter.h b/src/video_core/texture_cache/formatter.h index 33c32645a2..3e2e749274 100644 --- a/src/video_core/texture_cache/formatter.h +++ b/src/video_core/texture_cache/formatter.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -17,210 +20,9 @@ struct fmt::formatter : fmt::formatter Date: Sun, 17 May 2026 02:16:48 +0200 Subject: [PATCH 42/58] [docs] add CodingStyle + Coding guidelines, HOS kernel basics, 'Settings' and add external resources, add better docs for dtrace-tool.pl (#3964) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3964 Reviewed-by: MaranBr Reviewed-by: CamilleLaVey --- docs/Deps.md | 14 +- docs/HosKernel.md | 31 +++ docs/NvidiaGpu.md | 2 + docs/README.md | 28 ++- docs/Settings.md | 327 ++++++++++++++++++++++++++++++ docs/policies/Coding.md | 172 ++++++---------- docs/policies/CodingStyle.md | 126 ++++++++++++ docs/user/AddingBooleanToggles.md | 159 --------------- docs/user/AddingDebugKnobs.md | 167 --------------- docs/user/Multiplayer.md | 2 +- docs/user/README.md | 15 +- tools/dtrace-tool.pl | 66 +++--- 12 files changed, 614 insertions(+), 495 deletions(-) create mode 100644 docs/HosKernel.md create mode 100644 docs/Settings.md create mode 100644 docs/policies/CodingStyle.md delete mode 100644 docs/user/AddingBooleanToggles.md delete mode 100644 docs/user/AddingDebugKnobs.md diff --git a/docs/Deps.md b/docs/Deps.md index 744713d4f0..83ac0ac799 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -35,6 +35,11 @@ If you are on desktop and plan to use the Qt frontend, you *must* install Qt 6, * For help setting up Qt Creator, run `./install.sh -h qtcreator` +* If you're using clang-cl and want to still use MSVC + * Check the option to add "C++ clang compiler for Windows" on Visual Studio installer and uncheck "x64/x86 build tool for MSVC" while selecting "C++ desktop developement tools" and change Visual Studio to 2026, from 2022. + * At qt creator section generator tab change Visual Studio 17 2022 to 2026. + * Finally, to use clang-cl: `cmake -S . -B build -G "Visual Studio 17 2026" -T ClangCL` + If you are on **Windows** and building with **MSVC** or **clang-cl**, you may go [back home](Build.md) and continue. ## Externals @@ -264,7 +269,10 @@ If using FreeBSD 12 or prior, use `devel/pkg-config` instead.

NetBSD -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`. +For NetBSD +10.1: +```sh +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 frozen +``` [Caveats](./Caveats.md#netbsd). @@ -274,7 +282,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 qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 libusb1-1.0.29 +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 quazip-qt6 ``` [Caveats](./Caveats.md#openbsd). @@ -344,7 +352,7 @@ pacman -Syuu --needed --noconfirm $packages HaikuOS ```sh -pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.90_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 +pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.90_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 cubeb_devel simpleini quazip_qt6_devel ``` [Caveats](./Caveats.md#haikuos). diff --git a/docs/HosKernel.md b/docs/HosKernel.md new file mode 100644 index 0000000000..399d4fb7b1 --- /dev/null +++ b/docs/HosKernel.md @@ -0,0 +1,31 @@ +# HOS Kernel + +In brief, the HOS kernel is a microkernel, some services and programs run in userspace, the primary way to do communication between these is via `HIPC` (not covered here); otherwise most of the primitives reside in the forms of syscalls invoked via `svc #imm`. The kernel supports both 32-bit and 64-bit programs, and has the capacity to use 32, 36 and 39 bits of address space for spawned processes. Most of the networking stack is based off FreeBSD's network stack. + +The emulator implements the majority of the syscalls pertaining to the HOS kernel itself. When we talk about the HOS Kernel (in the context of the emulator) we are strictly speaking about the mechanisms from which syscalls are handled (and it's subsequent side effects, such as the page table book-keeping). The emulator at it's current state is unable to load a custom low-level kernel and do supervisor-level emulation. + +Most programs in NX eventually invoke an `svc`, which, depending on it's immediate value, will go on to be dispatched into one of the specific syscall handlers. + +These can be seen in [svc.cpp](/src/core/hle/kernel/svc.cpp). All of these correspond to syscalls which userspace programs may perform. + +In turn, these syscalls create the mechanisms that allows programs to use CMIF/TIPC as their primary IPC form to contact other services/processes running on the system, the details of which will not be covered here, but you can consult the relevant [SwitchBrew article: 'HIPC'](https://switchbrew.org/wiki/HIPC). + +From the point of view of the programs, no special devices (such as PCIE, Realtek drivers, Bluetooth or USB) has to be handled by the emulator; this is because most of the fun occurs in specialized services such as `usb:u` or `pcie` services. Which aren't emulated (yet). + +Due to the nature of syscalls, many of them interact with memory. The emulated kernel has an internal tree-like structure, borrowed from FreeBSD's intrusive red-black tree; this is used to track and find mappings added or removed. Thus most of the process space is emulated in this way. + +The kernel keeps it's own separate pagetable, in a traditional sense, each process has it's own pagetable, this is true for HOS as well. + +Every process keeps it's own tracking of the following structures: +- Name (13 characters) +- 64-bit ID +- A handle table +- Exclusive monitor +- Threads +- Held locks +- Thread local pages +- A page table for each process + +The emulator willingly restricts itself to only use 4 threads (to emulate 4 cores), this is because most existing applications do not benefit greatly from the added core count, and in fact can be detrimental due to extra contention. This translates equitatively to about 4 `ArmInterface` slots for each process, these are then redirected to whatever is the last `pc` of the last thread running on the core is meant to be; proceed to run it, then when returning (due to halt or interruption), proceed to reschedule the thread. + +The scheduler as-is isn't 100% faithful to the original, and has great timing variance (especially due to the fact the emulator can run in systems with wildly different timings). diff --git a/docs/NvidiaGpu.md b/docs/NvidiaGpu.md index d7fe3d86d3..a595f61a66 100644 --- a/docs/NvidiaGpu.md +++ b/docs/NvidiaGpu.md @@ -853,6 +853,8 @@ Texture Query. Vote Across SIMD Thread Group +`VOTE_vtg` is a kepler leftover. + # VSET `0100 000- ---- ----` diff --git a/docs/README.md b/docs/README.md index 68775f99d8..9e5f635b6f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,21 +2,26 @@ Are you just a casual user? Take a look at our [User Handbook](./user) then! +If you want to register/signup as a contributor, take a gander at the [signup guide](./SIGNUP.md). + 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)** +- **[General Build Instructions](./Build.md)** +- **[CMake Options](./Options.md)** +- **[Cross Compiling](./CrossCompile.md)** +- **[Development Guidelines](./Development.md)** +- **[Dependencies](./Deps.md)** - **[Debug Guidelines](./Debug.md)** - **[CPM - CMake Package Manager](./CPMUtil)** -- **[Platform-Specific Caveats](Caveats.md)** +- **[Platform-Specific Caveats](./Caveats.md)** - **[The NVIDIA SM86 (Maxwell) GPU](./NvidiaGpu.md)** -- **[Dynarmic](./dynarmic)** - **[Cross compilation](./CrossCompile.md)** - **[Driver Bugs](./DriverBugs.md)** - **[Building Older Commits](./build/OlderCommits.md)** +- Subsystems: + - **[Dynarmic](./dynarmic/README.md)** + - **[HOS Kernel](./HosKernel.md)** + - **[Settings](./Settings.md)** ## Policies @@ -25,3 +30,12 @@ Policies and information on development. - **[AI and LLM Usage](./policies/AI.md)** - **[Release Policy](./policies/Release.md)** - **[Coding guidelines](./policies/Coding.md)** +- **[Coding Style guidelines](./policies/CodingStyle.md)** + +## Externals + +Other useful resources in general, take a quick read if you need. + +- **[SwitchBrew](https://switchbrew.org/wiki/Main_Page)** +- **[IPS file format](https://zerosoft.zophar.net/ips.php)** +- **[IPSwitch file format](https://github.com/3096/ipswitch)** diff --git a/docs/Settings.md b/docs/Settings.md new file mode 100644 index 0000000000..4bae71f44e --- /dev/null +++ b/docs/Settings.md @@ -0,0 +1,327 @@ +# Settings + +> [!WARNING] +> This guide is intended for developers ONLY. If you're looking for configuring the emulator itself, please read **[the user handbook](./user/README.md)**. + +Settings on the emulator are very important, toggles and such can be used to guard and/or add branches to paths where some games may crash while others won't, and viceversa. + +However, this process can be tedious for those unfamiliar; this document serves as a outline/documentation for the settings subsystem. + +## Index + +* [Adding Debug Knobs](#adding-debug-knobs) + * [Advantages](#advantages) + * [Usage](#usage) + * [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) + * [Terminology and user communication](#terminology-and-user-communication) + * [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) + * [Best Practices](#best-practices) +* [Adding Boolean Settings Toggles](#adding-boolean-settings-toggles) + * [Step 1 - Common Setting](#step-1-common-setting) + * [Step 2 - Qt Toggle](#step-2-qt-toggle) + * [Step 3 - Kotlin (Android)](#step-3-kotlin-android) + * [Step 3.1 - BooleanSetting.kt](#step-3-1-booleansetting-kt) + * [Step 3.2 - SettingsItem.kt](#step-3-2-settingsitem-kt) + * [Step 3.3 - SettingsFragmentPresenter.kt](#step-3-3-settingsfragmentpresenter-kt) + * [Step 3.4 - Localization](#step-3-4-localization) + * [Step 4 - Use Your Toggle](#step-4-use-your-toggle) + * [Best Practices](#best-practices) + +## Adding Boolean Settings Toggles + +This guide will walk you through adding a new boolean toggle setting to Eden's configuration across both Qt's (PC) and Kotlin's (Android) UIs. + +--- + +### Step 1 - Common Setting + +Firstly add your desired toggle: + +Example: `src/common/setting.h` +```cpp +SwitchableSetting your_setting_name{linkage, false, "your_setting_name", Category::RendererExtensions}; +``` + +Remember to add your toggle to the appropriate category, for example: + +Common Categories: + +* Category::Renderer +* Category::RendererAdvanced +* Category::RendererExtensions +* Category::System +* Category::Core + +> [!WARNING] +> If you wish for your toggle to be `on by default` then change `false` to `true` after `linkage,`. + +--- + +### Step 2 - Qt Toggle + +Add the toggle to the Qt UI, where you wish for it to appear and place it there. + +Example: `src/qt_common/config/shared_translation.cpp` +```cpp +INSERT(Settings, + your_setting_name, + tr("Your Setting Display Name"), + tr("Detailed description of what this setting does.\n" + "You can use multiple lines.\n" + "Explain any caveats or requirements.")); +``` + +#### Make sure to: + +* Keep display naming consistant +* Put detailed info in the description +* Use `\n` for line breaks in descriptions + +--- + +### Step 3 - Kotlin (Android) + +#### Step 3.1 - BooleanSetting.kt + +Add where it should be in the settings. + +Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt` +```kts +RENDERER_YOUR_SETTING_NAME("your_setting_name"), +``` + +#### Make sure to: + +* Ensure the prefix naming matches the intended category. + +--- + +#### Step 3.2 - SettingsItem.kt + +Add the toggle to the Kotlin (Android) UI + +Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt` +```kts +put( + SwitchSetting( + BooleanSetting.RENDERER_YOUR_SETTING_NAME, + titleId = R.string.your_setting_name, + descriptionId = R.string.your_setting_name_description + ) +) +``` + +--- + +#### Step 3.3 - SettingsFragmentPresenter.kt + +Add your setting within the right category. + +Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt` +```kts +add(BooleanSetting.RENDERER_YOUR_SETTING_NAME.key) +``` + +> [!WARNING] +> Remember, placing matters! Settings appear in the order of where you add them. + +--- + +#### Step 3.4 - Localization + +Add your setting and description in the appropriate place. + +Example: `src/android/app/src/main/res/values/strings.xml` +```xml +Your Setting Display Name +Detailed description of what this setting does. Explain any caveats, requirements, or warnings here. +``` + +--- + +### Step 4 - Use Your Toggle! + +Now the UI part is done find a place in the code for the toggle, +And use it to your heart's desire! + +Example: +```cpp +const bool your_value = Settings::values.your_setting_name.GetValue(); + +if (your_value) { + // Do something when enabled +} +``` + +If you wish to do something only when the toggle is disabled, +Use `if (!your_value) {` instead of `if (your_value) {`. + +--- + +### Best Practices + +* Naming - Use clear, descriptive names. Something for both the devs and the users. +* Defaults - Choose safe default values (usually false for new features). +* Documentation - Write clear descriptions explaining when and why to use the setting. +* Categories - Put settings in the appropriate category. +* Order - Place related settings near each other. +* Testing - Always test on both PC and Android before committing when possible. + +Thank you for reading, I hope this guide helped you making your toggle! + +## Adding Debug Knobs + +Debug Knobs is a 16-bit integer setting (`debug_knobs`) in the Eden Emulator that serves as a bitmask for gating various testing and debugging features. This allows developers and advanced users to enable or disable specific debug behaviors without requiring deploying of complete but temporary toggles. + +The setting ranges from 0 to 65535 (0x0000 to 0xFFFF), where each bit represents a different debug feature flag. + +--- + +### Advantages + +The main advantage is to avoid deploying new disposable toggles (those made only for testing stage, and are disposed once new feature gets good to merge). This empowers devs to be free of all frontend burocracy and hassle of new toggles. + +Common advantages recap: + +* **Fine-Grained Control**: Enable or disable up to 16 individual debug features independently using bit manipulation on a single build +* **Runtime Configuration**: Change debug behavior at runtime the same way as new toggles would do +* **Safe incremental development**: New debug features can be added while impact can be isolated from previous deployments + +### Usage + +#### Accessing Debug Knobs (dev side) + +Use the `Settings::getDebugKnobAt(u8 i)` function to check if a specific bit is set: + +```cpp +//cpp side +#include "common/settings.h" + +// Check if bit 0 is set +bool feature_enabled = Settings::getDebugKnobAt(0); + +// Check if bit 15 is set +bool another_feature = Settings::getDebugKnobAt(15); +``` + +```kts +//kotlin side +import org.yuzu.yuzu_emu.features.settings.model.Settings + +// Check if bit x is set +bool feature_enabled = Settings.getDebugKnobAt(x); //x as integer from 0 to 15 +``` + +The function returns `true` if the specified bit (0-15) is set in the `debug_knobs` value, `false` otherwise. + +#### Setting Debug Knobs (user side) + +Developers must inform which knobs are tied to each functionality to be tested. + +The debug knobs value can be set through: + +1. **Desktop UI**: In the Debug configuration tab, there's a spinbox for "Debug knobs" (0-65535) +2. **Android UI**: Available as an integer setting in the Debug section +3. **Configuration Files**: Set the `debug_knobs` value in the emulator's configuration + +#### Bit Manipulation Examples + +To enable specific features, calculate the decimal value by setting the appropriate bits: + +* **Enable only bit 0**: Value = 1 (2^0) +* **Enable only bit 1**: Value = 2 (2^1) +* **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 + +```cpp +void SomeFunction() { + if (Settings::getDebugKnobAt(0)) { + LOG_DEBUG(Common, "Debug feature 0 is enabled"); + // Additional debug code here + } + + if (Settings::getDebugKnobAt(1)) { + LOG_DEBUG(Common, "Debug feature 1 is enabled"); + // Different debug behavior + } +} +``` + +#### Example 2: Performance Tuning + +```cpp +bool UseOptimizedPath() { + // Skip optimization if debug bit 2 is set for testing + return !Settings::getDebugKnobAt(2); +} +``` + +#### Example 3: Feature Gating + +```cpp +void ExperimentalFeature() { + static constexpr u8 EXPERIMENTAL_FEATURE_BIT = 3; + + if (!Settings::getDebugKnobAt(EXPERIMENTAL_FEATURE_BIT)) { + // Fallback to stable implementation + StableImplementation(); + return; + } + + // Experimental implementation + ExperimentalImplementation(); +} +``` + +### Best Practices + +* This setting is intended for development and testing purposes only +* Knobs must be unwired before PR creation +* The setting is per-game configurable, allowing different debug setups for different titles diff --git a/docs/policies/Coding.md b/docs/policies/Coding.md index c50f93b142..062e0beda4 100644 --- a/docs/policies/Coding.md +++ b/docs/policies/Coding.md @@ -1,126 +1,70 @@ # Coding guidelines -These are mostly "suggestions", if you feel like your code is readable, comprehensible to others; and most importantly doesn't result in unreadable spaghetti you're fine to go. +These are **not** stylistic guidelines, they're, for the most part, suggestions on how to architecture new systems or improve upon the existing codebase. -But for new developers you may find that following these guidelines will make everything x10 easier. +# Foreword -## Naming conventions +Don't try to micro-optimize out of the get go, while yes, most of the code is pretty, subpar, most of these are aftertoughts and details that can be glossed over **generally**. -Simply put, types/classes are named as `PascalCase`, same for methods and functions like `AddElement`. Variables are named `like_this_snake_case` and constants are `IN_SCREAMING_CASE`. +Architectural issues are more important, for example an API returning a `std::string` is not as efficient as one that operates on `std::string_view` directly (cost of constructing an `std::string` w/o small-string optimization and all of that). -Except for Qt MOC where `functionName` is preferred. +Regardless of the details, try to keep things simple. As a general rule of thumb. -Template typenames prefer short names like `T`, `I`, `U`, if a longer name is required either `Iterator` or `perform_action` are fine as well. Do not use names like `SS` as systems like solaris define it for registers, in general do not use any of the following for short names: +# C++ guidelines -- `SS`, `DS`, `GS`, `FS`: Segment registers, defined by Solaris `` -- `EAX`, `EBX`, `ECX`, `EDX`, `ESI`, `EDI`, `ESP`, `EBP`, `EIP`: Registers, defined by Solaris. -- `X`: Defined by some utility headers, avoid. -- `_`: Defined by gettext, avoid. -- `N`, `M`, `S`: Preferably don't use this for types, use it for numeric constants. -- `TR`: Used by some weird `` whom define the Task Register as a logical register to provide to the user... (Need to remember which OS in specific). +Everyone has their own way of viewing good/bad C++ practices, my general outline: -Macros must always be in `SCREAMING_CASE`. Do not use short letter macros as systems like Solaris will conflict with them; a good rule of thumb is >5 characters per macro - i.e `THIS_MACRO_IS_GOOD`, `AND_ALSO_THIS_ONE`. +- At your disposal you may use `boost::container::static_vector<>` (beware it has a ctor/initialization cost which goes up the more elements you add). + - Or you may use `boost::container::small_vector<>` (which has an initialization cost as well, and will use extra book-keeping for heap, try to keep a balance). +- Don't use `[[likely]]` or `[[unlikely]]`; PGO builds exist for that. +- Don't use inline assembly to try to outsmart the compiler unless you're 100% sure the assembly you're writing is actually good. + - And if so, try to restructure your C++ code so the compiler vectorizes it/makes it better, right? + - Or if that fails, use intrinsics instead of raw `asm volatile`. +- Use `std::optional<>` instead of `std::unique_ptr<>` if possible. + - `std::unique_ptr<>` carries indirection cost due to it being memory allocated on the heap. + - It isn't often that objects that contain `std::unique_ptr<>`, are allocated on the heap themselves, allocating even more things on the heap seems redundant. +- Avoid `std::recursive_mutex` at all costs. + - It's basically implemented as a linked list most of the time and has HEAVY performance penalties. +- Exploit the fact `std::atomic/std::atomic` is basically free on most arches that matter. + - In x86_64, an atomic `uint32_t` is basically `mov [m32], r32`, which is essentially free/cheap. +- Avoid template parameters unless you really need them. + - For small inlineable functions this is fine, for more complex ones, please consider the generated assembly. +- Dont make your own memcpy/memset/strcpy/strncpy/etc. + - Seriously DON'T DO THIS. You will NOT beat the compiler. + - Nor 30 years of writing optimized `mem*`. + - If your code is slow, don't blame `mem*`, blame your code. +- Try to avoid using `virtual` since vtable indirection has a cost +- Avoid `dynamic_cast` and `typeid` at all costs. + - The reason is because the project has `-fno-rtti` disabled by default, due to the costs of dynamic polymorphism. +- Always copy-on-value for objects with `sizeof(void *) >= sizeof(T) * 2`, i.e objects sized as 2 pointers or less, for bigger objects you can use ref/pointer as usual. +- Try using move semantics instead of references, whenever possible. +- Remember function parameters are extremelly cheap as fuck, don't be afraid to place upto 8 parameters on a given function. +- Don't save a reference in structures of a parent object, i.e: + ```c++ + struct Child { + Parent& parent; + void Mehod() { + parent.Something(); + } + }; + ``` + - Instead you can do the following: + ```c++ + struct Child { + void Mehod(Parent& parent) { + parent.Something(); + } + }; + ``` + - This reduces the amount of pointers you have lying around, and also works better because of the aforementioned cheapness of parameter functions. -Try not using hungarian notation, if you're able. +# Engineering guidelines -## Formatting +Coding isn't also writing stuff but architecturing stuff, consider the following: -Formatting is extremelly lax, the general rule of thumb is: Don't add new lines just to increase line count. The less lines we have to look at, the better. This means also packing densely your code while not making it a clusterfuck. Strike a balance of "this is a short and comprehensible piece of code" and "my eyes are actually happy to see this!". Don't just drop the entire thing in a single line and call it "dense code", that's just spaghetti posing as code. In general, be mindful of what other devs need to look at. - -Do not put if/while/etc braces after lines: - -```c++ -// no dont do this -// this is more lines of code for no good reason (why braces need their separate lines?) -// and those take space in someone's screen, cumulatively -if (thing) -{ //<-- - some(); // ... -} //<-- 2 lines of code for basically "opening" and "closing" an statment - -// do this -if (thing) { //<-- [...] and with your brain you can deduce it's this piece of code - // that's being closed - some(); // ... -} //<-- only one line, and it's clearer since you know its closing something [...] - -// or this, albeit the extra line isn't needed (at your discretion of course) -if (thing) - some(); // ... - -// this is also ok, keeps things in one line and makes it extremely clear -if (thing) some(); - -// NOT ok, don't be "clever" and use the comma operator to stash a bunch of statments -// in a single line, doing this will definitely ruin someone's day - just do the thing below -// vvv -if (thing) some(), thing(), a2(a1(), y1(), j1()), do_complex_shit(wa(), wo(), ploo()); -// ... and in general don't use the comma operator for "multiple statments", EXCEPT if you think -// that it makes the code more readable (the situation may be rare however) - -// Wow so much clearer! Now I can actually see what each statment is meant to do! -if (thing) { - some(); - thing(); - a2(a1(), y1(), j1()); - do_complex_shit(wa(), wo(), ploo()); -} -``` - -Brace rules are lax, if you can get the point across, do it: - -```c++ -// this is fine -do { - if (thing) { - return 0; - } -} while (other); - -// this is also ok --- albeit a bit more dense -do if (thing) return 0; while (other); - -// ok as well -do { - if (thing) return 0; -} while (other); -``` - -There is no 80-column limit but preferably be mindful of other developer's readability (like don't just put everything onto one line). - -```c++ -// someone is going to be mad due to this -SDL_AudioSpec obtained; -device_name.empty() ? device = SDL_OpenAudioDevice(nullptr, capture, &spec, &obtained, false) : device = SDL_OpenAudioDevice(device_name.c_str(), capture, &spec, &obtained, false); - -// maybe consider this -SDL_AudioSpec obtained; -if (device_name.empty()) { - device = SDL_OpenAudioDevice(nullptr, capture, &spec, &obtained, false); -} else { - device = SDL_OpenAudioDevice(device_name.c_str(), capture, &spec, &obtained, false); -} - -// or this is fine as well -SDL_AudioSpec obtained; -device = SDL_OpenAudioDevice(device_name.empty() ? nullptr : device_name.c_str(), capture, &spec, &obtained, false); -``` - -A note about operators: Use them sparingly, yes, the language is lax on them, but some usages can be... tripping to say the least. - -```c++ -a, b, c; //<-- NOT OK multiple statments with comma operator is definitely a recipe for disaster -return c ? a : b; //<-- OK ternaries at end of return statments are clear and fine -return a, b; //<-- NOT OK return will take value of `b` but also evaluate `a`, just use a separate statment -void f(int a[]) //<-- OK? if you intend to use the pointer as an array, otherwise just mark it as * -``` - -And about templates, use them sparingly, don't just do meta-templating for the sake of it, do it when you actually need it. This isn't a competition to see who can make the most complicated and robust meta-templating system. Just use what works, and preferably stick to the standard libary instead of reinventing the wheel. Additionally: - -```c++ -// NOT OK This will create (T * N * C * P) versions of the same function. DO. NOT. DO. THIS. -template inline void what() const noexcept; - -// OK use parameters like a normal person, don't be afraid to use them :) -template inline void what(size_t n, size_t c, size_t p) const noexcept; -``` +- Try to reduce dependency on... dependencies + - While some dependencies are useful `boost::container` and `fmt` to name a few, remember each dependency added incurs a cost. + - It may also be subpar with a hand rolled implementation, biggest exemplar of this is `spirv-tools` providing subpar SPIRV optimizations in comparison to the in-house optimizer. +- Try to rely less on indirection for architecturing systems + - If the underlying HLE kernel emulation requires it, try making a solution that keeps things local + - For example, there isn't a need for file descriptors to each be a pointer, when they could be a fixed table size with elements that may be emplaced at will. diff --git a/docs/policies/CodingStyle.md b/docs/policies/CodingStyle.md new file mode 100644 index 0000000000..659e8f7384 --- /dev/null +++ b/docs/policies/CodingStyle.md @@ -0,0 +1,126 @@ +# Coding Style guidelines + +These are mostly "suggestions", if you feel like your code is readable, comprehensible to others; and most importantly doesn't result in unreadable spaghetti you're fine to go. + +But for new developers you may find that following these guidelines will make everything x10 easier. + +## Naming conventions + +Simply put, types/classes are named as `PascalCase`, same for methods and functions like `AddElement`. Variables are named `like_this_snake_case` and constants are `IN_SCREAMING_CASE`. + +Except for Qt MOC where `functionName` is preferred. + +Template typenames prefer short names like `T`, `I`, `U`, if a longer name is required either `Iterator` or `perform_action` are fine as well. Do not use names like `SS` as systems like solaris define it for registers, in general do not use any of the following for short names: + +- `SS`, `DS`, `GS`, `FS`: Segment registers, defined by Solaris `` +- `EAX`, `EBX`, `ECX`, `EDX`, `ESI`, `EDI`, `ESP`, `EBP`, `EIP`: Registers, defined by Solaris. +- `X`: Defined by some utility headers, avoid. +- `_`: Defined by gettext, avoid. +- `N`, `M`, `S`: Preferably don't use this for types, use it for numeric constants. +- `TR`: Used by some weird `` whom define the Task Register as a logical register to provide to the user... (Need to remember which OS in specific). + +Macros must always be in `SCREAMING_CASE`. Do not use short letter macros as systems like Solaris will conflict with them; a good rule of thumb is >5 characters per macro - i.e `THIS_MACRO_IS_GOOD`, `AND_ALSO_THIS_ONE`. + +Try not using hungarian notation, if you're able. + +## Formatting + +Formatting is extremelly lax, the general rule of thumb is: Don't add new lines just to increase line count. The less lines we have to look at, the better. This means also packing densely your code while not making it a clusterfuck. Strike a balance of "this is a short and comprehensible piece of code" and "my eyes are actually happy to see this!". Don't just drop the entire thing in a single line and call it "dense code", that's just spaghetti posing as code. In general, be mindful of what other devs need to look at. + +Do not put if/while/etc braces after lines: + +```c++ +// no dont do this +// this is more lines of code for no good reason (why braces need their separate lines?) +// and those take space in someone's screen, cumulatively +if (thing) +{ //<-- + some(); // ... +} //<-- 2 lines of code for basically "opening" and "closing" an statment + +// do this +if (thing) { //<-- [...] and with your brain you can deduce it's this piece of code + // that's being closed + some(); // ... +} //<-- only one line, and it's clearer since you know its closing something [...] + +// or this, albeit the extra line isn't needed (at your discretion of course) +if (thing) + some(); // ... + +// this is also ok, keeps things in one line and makes it extremely clear +if (thing) some(); + +// NOT ok, don't be "clever" and use the comma operator to stash a bunch of statments +// in a single line, doing this will definitely ruin someone's day - just do the thing below +// vvv +if (thing) some(), thing(), a2(a1(), y1(), j1()), do_complex_shit(wa(), wo(), ploo()); +// ... and in general don't use the comma operator for "multiple statments", EXCEPT if you think +// that it makes the code more readable (the situation may be rare however) + +// Wow so much clearer! Now I can actually see what each statment is meant to do! +if (thing) { + some(); + thing(); + a2(a1(), y1(), j1()); + do_complex_shit(wa(), wo(), ploo()); +} +``` + +Brace rules are lax, if you can get the point across, do it: + +```c++ +// this is fine +do { + if (thing) { + return 0; + } +} while (other); + +// this is also ok --- albeit a bit more dense +do if (thing) return 0; while (other); + +// ok as well +do { + if (thing) return 0; +} while (other); +``` + +There is no 80-column limit but preferably be mindful of other developer's readability (like don't just put everything onto one line). + +```c++ +// someone is going to be mad due to this +SDL_AudioSpec obtained; +device_name.empty() ? device = SDL_OpenAudioDevice(nullptr, capture, &spec, &obtained, false) : device = SDL_OpenAudioDevice(device_name.c_str(), capture, &spec, &obtained, false); + +// maybe consider this +SDL_AudioSpec obtained; +if (device_name.empty()) { + device = SDL_OpenAudioDevice(nullptr, capture, &spec, &obtained, false); +} else { + device = SDL_OpenAudioDevice(device_name.c_str(), capture, &spec, &obtained, false); +} + +// or this is fine as well +SDL_AudioSpec obtained; +device = SDL_OpenAudioDevice(device_name.empty() ? nullptr : device_name.c_str(), capture, &spec, &obtained, false); +``` + +A note about operators: Use them sparingly, yes, the language is lax on them, but some usages can be... tripping to say the least. + +```c++ +a, b, c; //<-- NOT OK multiple statments with comma operator is definitely a recipe for disaster +return c ? a : b; //<-- OK ternaries at end of return statments are clear and fine +return a, b; //<-- NOT OK return will take value of `b` but also evaluate `a`, just use a separate statment +void f(int a[]) //<-- OK? if you intend to use the pointer as an array, otherwise just mark it as * +``` + +And about templates, use them sparingly, don't just do meta-templating for the sake of it, do it when you actually need it. This isn't a competition to see who can make the most complicated and robust meta-templating system. Just use what works, and preferably stick to the standard libary instead of reinventing the wheel. Additionally: + +```c++ +// NOT OK This will create (T * N * C * P) versions of the same function. DO. NOT. DO. THIS. +template inline void what() const noexcept; + +// OK use parameters like a normal person, don't be afraid to use them :) +template inline void what(size_t n, size_t c, size_t p) const noexcept; +``` diff --git a/docs/user/AddingBooleanToggles.md b/docs/user/AddingBooleanToggles.md deleted file mode 100644 index 1af5fd932d..0000000000 --- a/docs/user/AddingBooleanToggles.md +++ /dev/null @@ -1,159 +0,0 @@ -# User Handbook - Adding Boolean Settings Toggles - -> [!WARNING] -> This guide is intended for developers ONLY. If you are not a developer, this likely irrelevant to yourself. -> -> If you want to add temporary toggles, please refer to **[Adding Debug Knobs](AddingDebugKnobs.md)** - -This guide will walk you through adding a new boolean toggle setting to Eden's configuration across both Qt's (PC) and Kotlin's (Android) UIs. - -## Index - -1. [Step 1 - Common Setting](#step-1-common-setting) -2. [Step 2 - Qt Toggle](#step-2-qt-toggle) -3. [Step 3 - Kotlin (Android)](#step-3-kotlin-android) - - * [Step 3.1 - BooleanSetting.kt](#step-3-1-booleansetting-kt) - * [Step 3.2 - SettingsItem.kt](#step-3-2-settingsitem-kt) - * [Step 3.3 - SettingsFragmentPresenter.kt](#step-3-3-settingsfragmentpresenter-kt) - * [Step 3.4 - Localization](#step-3-4-localization) -4. [Step 4 - Use Your Toggle](#step-4-use-your-toggle) -5. [Best Practices](#best-practices) - ---- - -## Step 1 - Common Setting - -Firstly add your desired toggle: - -Example: `src/common/setting.h` -```cpp -SwitchableSetting your_setting_name{linkage, false, "your_setting_name", Category::RendererExtensions}; -``` - -### Remember to add your toggle to the appropriate category, for example: - -Common Categories: - -* Category::Renderer -* Category::RendererAdvanced -* Category::RendererExtensions -* Category::System -* Category::Core - -> [!WARNING] -> If you wish for your toggle to be `on by default` then change `false` to `true` after `linkage,`. - ---- - -## Step 2 - Qt Toggle - -Add the toggle to the Qt UI, where you wish for it to appear and place it there. - -Example: `src/qt_common/config/shared_translation.cpp` -```cpp -INSERT(Settings, - your_setting_name, - tr("Your Setting Display Name"), - tr("Detailed description of what this setting does.\n" - "You can use multiple lines.\n" - "Explain any caveats or requirements.")); -``` - -### Make sure to: - -* Keep display naming consistant -* Put detailed info in the description -* Use `\n` for line breaks in descriptions - ---- - -## Step 3 - Kotlin (Android) - -### Step 3.1 - BooleanSetting.kt - -Add where it should be in the settings. - -Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt` -```kts -RENDERER_YOUR_SETTING_NAME("your_setting_name"), -``` - -### Make sure to: - -* Ensure the prefix naming matches the intended category. - ---- - -### Step 3.2 - SettingsItem.kt - -Add the toggle to the Kotlin (Android) UI - -Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt` -```kts -put( - SwitchSetting( - BooleanSetting.RENDERER_YOUR_SETTING_NAME, - titleId = R.string.your_setting_name, - descriptionId = R.string.your_setting_name_description - ) -) -``` - ---- - -### Step 3.3 - SettingsFragmentPresenter.kt - -Add your setting within the right category. - -Example: `src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt` -```kts -add(BooleanSetting.RENDERER_YOUR_SETTING_NAME.key) -``` - -> [!WARNING] -> Remember, placing matters! Settings appear in the order of where you add them. - ---- - -### Step 3.4 - Localization - -Add your setting and description in the appropriate place. - -Example: `src/android/app/src/main/res/values/strings.xml` -```xml -Your Setting Display Name -Detailed description of what this setting does. Explain any caveats, requirements, or warnings here. -``` - ---- - -## Step 4 - Use Your Toggle! - -Now the UI part is done find a place in the code for the toggle, -And use it to your heart's desire! - -Example: -```cpp -const bool your_value = Settings::values.your_setting_name.GetValue(); - -if (your_value) { - // Do something when enabled -} -``` - -If you wish to do something only when the toggle is disabled, -Use `if (!your_value) {` instead of `if (your_value) {`. - ---- - -## Best Practices - -* Naming - Use clear, descriptive names. Something for both the devs and the users. -* Defaults - Choose safe default values (usually false for new features). -* Documentation - Write clear descriptions explaining when and why to use the setting. -* Categories - Put settings in the appropriate category. -* Order - Place related settings near each other. -* Testing - Always test on both PC and Android before committing when possible. - -### Thank you for reading, I hope this guide helped you making your toggle! diff --git a/docs/user/AddingDebugKnobs.md b/docs/user/AddingDebugKnobs.md deleted file mode 100644 index 83db52b375..0000000000 --- a/docs/user/AddingDebugKnobs.md +++ /dev/null @@ -1,167 +0,0 @@ -# User Handbook - Adding Debug Knobs - -Debug Knobs is a 16-bit integer setting (`debug_knobs`) in the Eden Emulator that serves as a bitmask for gating various testing and debugging features. This allows developers and advanced users to enable or disable specific debug behaviors without requiring deploying of complete but temporary toggles. - -The setting ranges from 0 to 65535 (0x0000 to 0xFFFF), where each bit represents a different debug feature flag. - -## Index - -1. [Advantages](#advantages) -2. [Usage](#usage) - - * [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. [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) -5. [Best Practices](#best-practices) - ---- - -## Advantages - -The main advantage is to avoid deploying new disposable toggles (those made only for testing stage, and are disposed once new feature gets good to merge). This empowers devs to be free of all frontend burocracy and hassle of new toggles. - -Common advantages recap: - -* **Fine-Grained Control**: Enable or disable up to 16 individual debug features independently using bit manipulation on a single build -* **Runtime Configuration**: Change debug behavior at runtime the same way as new toggles would do -* **Safe incremental development**: New debug features can be added while impact can be isolated from previous deployments - -## Usage - -### Accessing Debug Knobs (dev side) - -Use the `Settings::getDebugKnobAt(u8 i)` function to check if a specific bit is set: - -```cpp -//cpp side -#include "common/settings.h" - -// Check if bit 0 is set -bool feature_enabled = Settings::getDebugKnobAt(0); - -// Check if bit 15 is set -bool another_feature = Settings::getDebugKnobAt(15); -``` - -```kts -//kotlin side -import org.yuzu.yuzu_emu.features.settings.model.Settings - -// Check if bit x is set -bool feature_enabled = Settings.getDebugKnobAt(x); //x as integer from 0 to 15 -``` - -The function returns `true` if the specified bit (0-15) is set in the `debug_knobs` value, `false` otherwise. - -### Setting Debug Knobs (user side) - -Developers must inform which knobs are tied to each functionality to be tested. - -The debug knobs value can be set through: - -1. **Desktop UI**: In the Debug configuration tab, there's a spinbox for "Debug knobs" (0-65535) -2. **Android UI**: Available as an integer setting in the Debug section -3. **Configuration Files**: Set the `debug_knobs` value in the emulator's configuration - -### Bit Manipulation Examples - -To enable specific features, calculate the decimal value by setting the appropriate bits: - -* **Enable only bit 0**: Value = 1 (2^0) -* **Enable only bit 1**: Value = 2 (2^1) -* **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 - -```cpp -void SomeFunction() { - if (Settings::getDebugKnobAt(0)) { - LOG_DEBUG(Common, "Debug feature 0 is enabled"); - // Additional debug code here - } - - if (Settings::getDebugKnobAt(1)) { - LOG_DEBUG(Common, "Debug feature 1 is enabled"); - // Different debug behavior - } -} -``` - -### Example 2: Performance Tuning - -```cpp -bool UseOptimizedPath() { - // Skip optimization if debug bit 2 is set for testing - return !Settings::getDebugKnobAt(2); -} -``` - -### Example 3: Feature Gating - -```cpp -void ExperimentalFeature() { - static constexpr u8 EXPERIMENTAL_FEATURE_BIT = 3; - - if (!Settings::getDebugKnobAt(EXPERIMENTAL_FEATURE_BIT)) { - // Fallback to stable implementation - StableImplementation(); - return; - } - - // Experimental implementation - ExperimentalImplementation(); -} -``` - -## Best Practices - -* This setting is intended for development and testing purposes only -* Knobs must be unwired before PR creation -* The setting is per-game configurable, allowing different debug setups for different titles diff --git a/docs/user/Multiplayer.md b/docs/user/Multiplayer.md index 57c4495f46..40e5dedc19 100644 --- a/docs/user/Multiplayer.md +++ b/docs/user/Multiplayer.md @@ -1,4 +1,4 @@ -# Multiplayer +# User Handbook - Multiplayer Use this guide to answer questions regarding and to start using the multiplayer functionality of Eden. ## Multiplayer FAQ diff --git a/docs/user/README.md b/docs/user/README.md index c1c4cd200a..0b1a434a37 100644 --- a/docs/user/README.md +++ b/docs/user/README.md @@ -25,12 +25,12 @@ A copy of this handbook is [available online](https://git.eden-emu.dev/eden-emu/ - **[Importing Saves](./ImportingSaves.md)** - **[Installing Atmosphere Mods](./InstallingAtmosphereMods.md)** - **[Installing Updates & DLCs](./InstallingUpdatesDLC.md)** -- **[Alter Date & Time](./AlterDateTime.md)** +- **[Multiplayer](./Multiplayer.md)** ## 3rd-party Integration - **[Configuring Steam ROM Manager](./SteamROM.md)** -- **[Server hosting](ServerHosting.md)** +- **[Server hosting](./ServerHosting.md)** - **[Syncthing Guide](./SyncthingGuide.md)** - **[Third Party](./ThirdParty.md)** - **[Obtainium](./ThirdParty.md#configuring-obtainium)** @@ -40,12 +40,13 @@ A copy of this handbook is [available online](https://git.eden-emu.dev/eden-emu/ ## Advanced +- **[Command Line](./CommandLine.md)** - **[Custom Firmware](./CFW.md)** +- **[Alter Date & Time](./AlterDateTime.md)** - **[How To Access Logs](./HowToAccessLogs.md)** - **[Gyro Controls](./GyroControls.md)** -- **[Platforms and Architectures](Architectures.md)** -- **[Command Line](CommandLine.md)** -- **[Native Application Development](Native.md)** -- **[Adding Boolean Settings Toggles](AddingBooleanToggles.md)** +- **[Platforms and Architectures](./Architectures.md)** +- **[Native Application Development](./Native.md)** +- **[Adding Boolean Settings Toggles](./AddingBooleanToggles.md)** - **[Adding Debug Knobs](./AddingDebugKnobs.md)** -- **[Testing](Testing.md)** +- **[Testing](./Testing.md)** diff --git a/tools/dtrace-tool.pl b/tools/dtrace-tool.pl index 2c4e7d6876..d143d36f3e 100755 --- a/tools/dtrace-tool.pl +++ b/tools/dtrace-tool.pl @@ -9,9 +9,11 @@ use warnings; use POSIX qw(strftime); my $input; -my $sampling_hz = '4000'; -my $sampling_time = '5'; +my $sampling_hz = '997'; +my $sampling_time = '60'; my $sampling_pid = `pgrep eden`; +chomp($sampling_pid); + my $sampling_program = 'eden'; my $sampling_type = 0; @@ -39,43 +41,27 @@ sub dtrace_ask_params { sub dtrace_probe_profiling { if ($sampling_type eq 0) { + # profile both kernel stacks and user stacks return " -profile-".$sampling_hz." /pid == ".$sampling_pid." && arg0/ { - @[stack(100)] = count(); -} -profile-".$sampling_hz." /pid == ".$sampling_pid." && arg1/ { - @[ustack(100)] = count(); -} -tick-".$sampling_time."s { - exit(0); -}"; +profile-".$sampling_hz." /pid == ".$sampling_pid." && arg0/ { @[stack(100)] = count(); } +profile-".$sampling_hz." /pid == ".$sampling_pid." && arg1/ { @[ustack(100)] = count(); } +tick-".$sampling_time."s { exit(0); }"; } elsif ($sampling_type eq 1) { + # trace syscall entries return " -syscall:::entry /pid == ".$sampling_pid."/ { - \@traces[ustack(100)] = count(); -} -tick-".$sampling_time."s { - exit(0); -}"; +syscall:::entry /pid == ".$sampling_pid."/ { \@traces[ustack(100)] = count(); } +tick-".$sampling_time."s { exit(0); }"; } elsif ($sampling_type eq 2) { + # profile both kernel and user stacks with thread names attached return " -profile-".$sampling_hz." /pid == ".$sampling_pid." && arg0/ { - @[stringof(curthread->td_name), stack(100)] = count(); -} -profile-".$sampling_hz." /pid == ".$sampling_pid." && arg1/ { - @[stringof(curthread->td_name), ustack(100)] = count(); -} -tick-".$sampling_time."s { - exit(0); -}"; +profile-".$sampling_hz." /pid == ".$sampling_pid." && arg0/ { @[stringof(curthread->td_name), stack(100)] = count(); } +profile-".$sampling_hz." /pid == ".$sampling_pid." && arg1/ { @[stringof(curthread->td_name), ustack(100)] = count(); } +tick-".$sampling_time."s { exit(0); }"; } elsif ($sampling_type eq 3) { + # trace I/O requests return " -io::start /pid == ".$sampling_pid."/ { - @[ustack(100)] = count(); -} -tick-".$sampling_time."s { - exit(0); -}"; +io::start /pid == ".$sampling_pid."/ { @[ustack(100)] = count(); } +tick-".$sampling_time."s { exit(0); }"; } else { die "idk"; } @@ -111,11 +97,17 @@ sub dtrace_generate { foreach my $i (0 .. $#ARGV) { if ($ARGV[$i] eq '-h') { - print "Usage: $0\n"; - printf "%-20s%s\n", "-p", "Prompt for parameters"; - printf "%-20s%s\n", "-g", "Generate dtrace output"; - printf "%-20s%s\n", "-s", "Continously generate output until Ctrl^C"; - printf "%-20s%s\n", "-", "Select dtrace type"; + print " +Usage: $0\n +-p Prompt for parameters\n +-g Generate dtrace output\n +-s Continously generate output until Ctrl^C\n +- Select dtrace type\n + 0: Profile kernel + user stacks (default)\n + 1: Trace syscall entries\n + 2: Profile kernel + user stacks with thread names\n + 3: Trace I/O requests\n +"; } elsif ($ARGV[$i] eq '-g') { dtrace_generate; } elsif ($ARGV[$i] eq '-s') { From 5aba461cb3dd9979633c0554e6be6b835c3710c9 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sun, 17 May 2026 02:17:11 +0200 Subject: [PATCH 43/58] [common/wall_clock] fix invariant RDTSC divide by 0 (#3961) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3961 Reviewed-by: MaranBr Reviewed-by: CamilleLaVey --- src/common/wall_clock.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp index bff9e7b4f4..c06f9b6318 100644 --- a/src/common/wall_clock.cpp +++ b/src/common/wall_clock.cpp @@ -22,11 +22,11 @@ namespace Common { WallClock::WallClock(bool invariant_, u64 rdtsc_frequency_) noexcept : invariant{invariant_} , rdtsc_frequency{rdtsc_frequency_} - , ns_rdtsc_factor{GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency_)} - , us_rdtsc_factor{GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency_)} - , ms_rdtsc_factor{GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency_)} - , cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency_)} - , gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency_)} + , ns_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(NsRatio::den, rdtsc_frequency_)} + , us_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(UsRatio::den, rdtsc_frequency_)} + , ms_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(MsRatio::den, rdtsc_frequency_)} + , cntpct_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency_)} + , gputick_rdtsc_factor{invariant_ ? 0 : GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency_)} {} std::chrono::nanoseconds WallClock::GetTimeNS() const { @@ -186,7 +186,7 @@ bool WallClock::IsNative() const { WallClock CreateOptimalClock() noexcept { #if defined(ARCHITECTURE_x86_64) auto const& caps = GetCPUCaps(); - return WallClock(!(caps.invariant_tsc && caps.tsc_frequency >= std::nano::den), std::max(caps.tsc_frequency, 1)); + return WallClock(!(caps.invariant_tsc && caps.tsc_frequency >= std::nano::den), caps.tsc_frequency); #elif defined(HAS_NCE) return WallClock(false, 1); #else From 945ea630b40870c86d52e080b3bb39d75c0e256b Mon Sep 17 00:00:00 2001 From: Eden CI Date: Sun, 17 May 2026 22:45:59 +0200 Subject: [PATCH 44/58] [dist, android] Update translations from Transifex for May 16 (#3960) Automatic translation update for May 16 Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3960 --- dist/languages/ar.ts | 106 ++++---- dist/languages/ca.ts | 106 ++++---- dist/languages/cs.ts | 106 ++++---- dist/languages/da.ts | 106 ++++---- dist/languages/de.ts | 106 ++++---- dist/languages/el.ts | 106 ++++---- dist/languages/es.ts | 106 ++++---- dist/languages/fi.ts | 106 ++++---- dist/languages/fr.ts | 106 ++++---- dist/languages/hu.ts | 106 ++++---- dist/languages/id.ts | 106 ++++---- dist/languages/it.ts | 106 ++++---- dist/languages/ja_JP.ts | 106 ++++---- dist/languages/ko_KR.ts | 233 ++++++++++-------- dist/languages/nb.ts | 106 ++++---- dist/languages/nl.ts | 106 ++++---- dist/languages/pl.ts | 106 ++++---- dist/languages/pt_BR.ts | 106 ++++---- dist/languages/pt_PT.ts | 106 ++++---- dist/languages/ru_RU.ts | 106 ++++---- dist/languages/sv.ts | 106 ++++---- dist/languages/tr_TR.ts | 106 ++++---- dist/languages/uk.ts | 106 ++++---- dist/languages/vi.ts | 106 ++++---- dist/languages/vi_VN.ts | 106 ++++---- dist/languages/zh_CN.ts | 106 ++++---- dist/languages/zh_TW.ts | 106 ++++---- .../app/src/main/res/values-es/strings.xml | 5 + .../src/main/res/values-zh-rCN/strings.xml | 12 +- 29 files changed, 1518 insertions(+), 1488 deletions(-) diff --git a/dist/languages/ar.ts b/dist/languages/ar.ts index 7b6a92dc6a..8eb16efe96 100644 --- a/dist/languages/ar.ts +++ b/dist/languages/ar.ts @@ -9310,10 +9310,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel إلغاء @@ -9334,7 +9334,7 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 @@ -9343,204 +9343,204 @@ p, li { white-space: pre-wrap; } %1 - - + + Verifying integrity... جارٍ التحقق من السلامة... - - + + Integrity verification succeeded! تم التحقق من السلامة بنجاح! - - + + The operation completed successfully. اكتملت العملية بنجاح. - - + + Integrity verification failed! فشل التحقق من السلامة! - + File contents may be corrupt or missing. قد تكون محتويات الملف تالفة أو مفقودة. - + Integrity verification couldn't be performed تعذر إجراء التحقق من السلامة - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. تم إلغاء تثبيت الفيرموير، قد يكون الفيرموير في حالة سيئة أو تآلف. تعذر التحقق من صحة محتويات الملف. - + Select Dumped Keys Location حدد موقع المفاتيح المفرغة - + Decryption Keys install succeeded تم تثبيت مفاتيح فك التشفير بنجاح - + Decryption Keys install failed فشل تثبيت مفاتيح فك التشفير - + Orphaned Profiles Detected! تم الكشف عن ملفات تعريف مهملة! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> قد تحدث أمور سيئة غير متوقعة إذا لم تقرأ هذا<br>!لقد اكتشف إيدن مجلدات الحفظ التالية بدون ملف تعريف مرفق:<br>%1<br><br>ملفات التعريف التالية صالحة:<br>%2<br><br>انقر على ”موافق“ لفتح مجلد الحفظ وإصلاح ملفات التعريف الخاصة بك.<br>تلميح: انسخ محتويات المجلد الأكبر أو آخر مجلد تم تعديله إلى مكان آخر، واحذف جميع ملفات التعريف اليتيمة، وانقل المحتويات المنسوخة إلى ملف التعريف الصحيح.<br><br>هل ما زلت تشعر بالارتباك؟ انظر إلى <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>صفحة المساعدة</a>.<br> - + Really clear data? مسح البيانات بالفعل؟ - + Important data may be lost! قد يتم فقدان بيانات مهمة! - + Are you REALLY sure? هل أنت متأكد حقًا؟ - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. بمجرد حذفها، لن تتمكن من استعادة بياناتك! قم بذلك فقط إذا كنت متأكدًا بنسبة 100٪ أنك تريد حذف هذه البيانات. - + Clearing... إزالة... - + Select Export Location حدد موقع التصدير - + %1.zip %1.zip - - + + Zipped Archives (*.zip) Zipped Archives (*.zip) - + Exporting data. This may take a while... تصدير البيانات. قد يستغرق هذا بعض الوقت... - + Exporting التصدير - + Exported Successfully تم التصدير بنجاح - + Data was exported successfully. تم تصدير البيانات بنجاح. - + Export Cancelled تم إلغاء التصدير - + Export was cancelled by the user. تم إلغاء التصدير من قبل المستخدم. - + Export Failed فشل التصدير - + Ensure you have write permissions on the targeted directory and try again. تأكد من أن لديك أذونات الكتابة على المجلد المحدد وحاول مرة أخرى. - + Select Import Location حدد موقع الاستيراد - + Import Warning تحذير الاستيراد - + All previous data in this directory will be deleted. Are you sure you wish to proceed? سيتم حذف جميع البيانات السابقة في هذا المجلد. هل أنت متأكد من رغبتك في المتابعة؟ - + Importing data. This may take a while... استيراد البيانات. قد يستغرق هذا بعض الوقت... - + Importing استيراد - + Imported Successfully تم الاستيراد بنجاح - + Data was imported successfully. تم استيراد البيانات بنجاح. - + Import Cancelled تم إلغاء الاستيراد - + Import was cancelled by the user. تم إلغاء الاستيراد من قبل المستخدم. - + Import Failed فشل الاستيراد - + Ensure you have read permissions on the targeted directory and try again. تأكد من أن لديك أذونات قراءة على المجلد المحدد وحاول مرة أخرى. @@ -9902,18 +9902,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed فشل استخراج التعديل - + Failed to create temporary directory %1 %1 فشل إنشاء مجلد المؤقت - + Zip file %1 is empty الملف المضغوط 1% فارغ diff --git a/dist/languages/ca.ts b/dist/languages/ca.ts index 10db8a5e3a..8e35230811 100644 --- a/dist/languages/ca.ts +++ b/dist/languages/ca.ts @@ -9202,10 +9202,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel Cancel·lar @@ -9226,210 +9226,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting Exportant - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9786,18 +9786,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/cs.ts b/dist/languages/cs.ts index b7469b5d5c..040a711d05 100644 --- a/dist/languages/cs.ts +++ b/dist/languages/cs.ts @@ -9190,10 +9190,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9214,210 +9214,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9774,18 +9774,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/da.ts b/dist/languages/da.ts index 91380077a2..df9d3804d6 100644 --- a/dist/languages/da.ts +++ b/dist/languages/da.ts @@ -9194,10 +9194,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9218,210 +9218,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9778,18 +9778,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/de.ts b/dist/languages/de.ts index 93652b117d..2c237d6ee4 100644 --- a/dist/languages/de.ts +++ b/dist/languages/de.ts @@ -9214,10 +9214,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9238,210 +9238,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9798,18 +9798,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/el.ts b/dist/languages/el.ts index ba849128fa..86481e1373 100644 --- a/dist/languages/el.ts +++ b/dist/languages/el.ts @@ -9186,10 +9186,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9210,210 +9210,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9770,18 +9770,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/es.ts b/dist/languages/es.ts index 115ca93dc6..087a4f80a3 100644 --- a/dist/languages/es.ts +++ b/dist/languages/es.ts @@ -9316,10 +9316,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel Cancelar @@ -9340,7 +9340,7 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 @@ -9349,206 +9349,206 @@ p, li { white-space: pre-wrap; } %1 - - + + Verifying integrity... Verificando integridad... - - + + Integrity verification succeeded! ¡La verificación de integridad ha sido un éxito! - - + + The operation completed successfully. La operación se completó con éxito. - - + + Integrity verification failed! ¡Verificación de integridad se fallo! - + File contents may be corrupt or missing. Los contenidos del archivo pueden estar corruptos. - + Integrity verification couldn't be performed No se pudo ejecutar la verificación de integridad - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. Instalacion de firmware cancellado , firmware podria estar en un mal estado o coruptos. contenidos de el archivo no pudieron ser verificados para validez. - + Select Dumped Keys Location Seleccionar ubicación de origen de los llaves volcados - + Decryption Keys install succeeded Instalación de llaves de descifra salo con exito - + Decryption Keys install failed Instalacion de las llaves de descifra se fallo - + Orphaned Profiles Detected! ¡Se detectaron perfiles huérfanos! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> ¡PODRÍAN SUCEDER COSAS MALAS E INESPERADAS SI NO LEE ESTO!<br>Eden ha detectado que los siguientes directorios de guardado no tienen perfil asociado:<br>%1<br><br>Los siguientes perfiles son válidos:<br>%2<br><br>Haga clic en "Aceptar" para abrir la carpeta de guardado y arreglar sus perfiles.<br>Consejo: copie el contenido de la carpeta más grande o la última modificada en otro lugar, elimine todos los perfiles huérfanos y mueva el contenido copiado al perfil correcto.<br><br>¿Aún tiene dudas? Consulte la <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>página de ayuda</a>.<br> - + Really clear data? ¿Realmente deseas borrar los datos? - + Important data may be lost! ¡Podrías perder información importante! - + Are you REALLY sure? ¿Estás REALMENTE seguro? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. ¡Una vez eliminados, tus datos no podrán recuperarse! Haz esto solo si estás 100% seguro de que deseas borrarlos. - + Clearing... Limpiando... - + Select Export Location Selecciona la Ubicación de Exportación. - + %1.zip %1.zip - - + + Zipped Archives (*.zip) Archivos comprimidos (*.zip) - + Exporting data. This may take a while... Exportando datos. Esto puede tardar un poco... - + Exporting Exportando - + Exported Successfully Exportación Exitosa. - + Data was exported successfully. Los datos se exportaron correctamente. - + Export Cancelled Exportación cancelada. - + Export was cancelled by the user. La exportación fue cancelada por el usuario. - + Export Failed Exportación Fallida - + Ensure you have write permissions on the targeted directory and try again. Asegúrate de tener permisos de escritura en el directorio seleccionado e inténtalo nuevamente. - + Select Import Location Seleccionar ubicación de importación. - + Import Warning Advertencia al importar datos - + All previous data in this directory will be deleted. Are you sure you wish to proceed? Todos los datos anteriores en este directorio serán eliminados. ¿Estás seguro de que deseas continuar? - + Importing data. This may take a while... Importando datos. Esto puede tomar unos minutos... - + Importing Importando - + Imported Successfully Importación completada con éxito. - + Data was imported successfully. Los datos se importaron correctamente. - + Import Cancelled La importación fue cancelada. - + Import was cancelled by the user. La importación fue cancelada por el usuario. - + Import Failed Importación Fallida. - + Ensure you have read permissions on the targeted directory and try again. Asegúrate de tener permisos de lectura en el directorio seleccionado e inténtalo nuevamente. @@ -9912,18 +9912,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed Fallo al extraer el mod - + Failed to create temporary directory %1 Fallo al crear directorio temporal %1 - + Zip file %1 is empty El archivo zip %1 está vacío diff --git a/dist/languages/fi.ts b/dist/languages/fi.ts index 41917c09db..34eec963df 100644 --- a/dist/languages/fi.ts +++ b/dist/languages/fi.ts @@ -9163,10 +9163,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9187,210 +9187,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9747,18 +9747,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/fr.ts b/dist/languages/fr.ts index d53b1902d4..836a4798b2 100644 --- a/dist/languages/fr.ts +++ b/dist/languages/fr.ts @@ -9273,10 +9273,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel Annuler @@ -9297,7 +9297,7 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 @@ -9306,204 +9306,204 @@ p, li { white-space: pre-wrap; } %1 - - + + Verifying integrity... Vérification de l'intégrité... - - + + Integrity verification succeeded! La vérification de l'intégrité réussi ! - - + + The operation completed successfully. L'opération s'est déroulée avec succès. - - + + Integrity verification failed! La vérification de l'intégrité a échoué ! - + File contents may be corrupt or missing. Le contenu d'un fichier peut être corrompu or manquant. - + Integrity verification couldn't be performed La vérification de l'intégrité n'a pas pu être effectuée - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. Installation du firmware annulée, le firmware est peut-être en mauvais état ou corrompu. Impossible de vérifier la validité du contenu du fichier. - + Select Dumped Keys Location Sélectionner Emplacement Clés Extraites - + Decryption Keys install succeeded Installation des clés de décryptage avec succès - + Decryption Keys install failed Installation des clés de décryptage échoué - + Orphaned Profiles Detected! Profils orphelins détectés ! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> DES CHOSES GRAVES INATTENDUES PEUVENT SURVENIR SI VOUS NE LISEZ PAS CECI !<br>Eden a détecté les répertoires de sauvegarde suivants sans profil associé :<br>%1<br><br>Les profils suivants sont valides :<br>%2<br><br>Cliquez sur « OK » pour ouvrir votre dossier de sauvegarde et corriger vos profils.<br>Astuce : copiez le contenu du dossier le plus volumineux ou le plus récemment modifié ailleurs, supprimez tous les profils orphelins et déplacez le contenu copié vers le profil correct.<br><br>Toujours confus ? Consultez la <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>page d’aide</a>.<br> - + Really clear data? Vraiment effacer les données ? - + Important data may be lost! Des données importantes peuvent être perdues ! - + Are you REALLY sure? Êtes-vous VRAIMENT sûr ? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. Une fois supprimées, vos données NE POURRONT PAS être récupérées ! Ne faites cela que si vous êtes sûr à 100 % de vouloir supprimer ces données. - + Clearing... Suppression en cours… - + Select Export Location Sélectionner l’emplacement d’exportation - + %1.zip %1.zip - - + + Zipped Archives (*.zip) Archives compressées (*.zip) - + Exporting data. This may take a while... Exportation des données en cours. Cela peut prendre un certain temps… - + Exporting Exportation en cours… - + Exported Successfully Exportation réussie - + Data was exported successfully. Les données ont été exportées avec succès. - + Export Cancelled Exportation annulée - + Export was cancelled by the user. L’exportation a été annulée par l’utilisateur. - + Export Failed Échec de l’exportation - + Ensure you have write permissions on the targeted directory and try again. Assurez-vous d’avoir les permissions d’écriture sur le répertoire ciblé et réessayez. - + Select Import Location Sélectionner l’emplacement d’importation - + Import Warning Avertissement d’importation - + All previous data in this directory will be deleted. Are you sure you wish to proceed? Toutes les données précédentes de ce répertoire seront supprimées. Êtes-vous sûr de vouloir continuer ? - + Importing data. This may take a while... Importation des données en cours. Cela peut prendre un certain temps… - + Importing Importation en cours… - + Imported Successfully Importation réussie - + Data was imported successfully. Les données ont été importées avec succès. - + Import Cancelled Importation annulée - + Import was cancelled by the user. L’importation a été annulée par l’utilisateur. - + Import Failed Échec de l’importation - + Ensure you have read permissions on the targeted directory and try again. Assurez-vous d’avoir les permissions de lecture sur le répertoire ciblé et réessayez. @@ -9863,18 +9863,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/hu.ts b/dist/languages/hu.ts index a9067946f0..8175e6e446 100644 --- a/dist/languages/hu.ts +++ b/dist/languages/hu.ts @@ -9185,10 +9185,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9209,210 +9209,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9769,18 +9769,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/id.ts b/dist/languages/id.ts index d759c99d70..78cb499ac4 100644 --- a/dist/languages/id.ts +++ b/dist/languages/id.ts @@ -9214,10 +9214,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9238,210 +9238,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9798,18 +9798,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/it.ts b/dist/languages/it.ts index d85159bdc2..bf25a6feb8 100644 --- a/dist/languages/it.ts +++ b/dist/languages/it.ts @@ -9301,10 +9301,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel Annulla @@ -9325,7 +9325,7 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 @@ -9334,204 +9334,204 @@ p, li { white-space: pre-wrap; } %1 - - + + Verifying integrity... Verifica dell'integrità in corso... - - + + Integrity verification succeeded! Verifica dell'integrità riuscita! - - + + The operation completed successfully. L'operazione è stata completata con successo. - - + + Integrity verification failed! Verifica dell'integrità fallita! - + File contents may be corrupt or missing. I contenuti dei file potrebbero essere corrotti o mancanti. - + Integrity verification couldn't be performed Impossibile effettuare la verifica dell'integrità - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. Installazione del firmware annullata, il firmware potrebbe essere corrotto o in cattivo stato. Non è stato possibile controllare la validità dei contenuti dei file. - + Select Dumped Keys Location Seleziona il percorso delle chiavi estratte - + Decryption Keys install succeeded Installazione delle chiavi di crittografia riuscita - + Decryption Keys install failed Installazione delle chiavi di crittografia fallita - + Orphaned Profiles Detected! Rilevati profili scollegati! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? Eliminare i dati? - + Important data may be lost! Potresti perdere dei dati importanti! - + Are you REALLY sure? Sei DAVVERO sicuro? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. Una volta eliminati, i tuoi dati NON potranno essere ripristinati! Procedi solo se sei assolutamente sicuro di voler eliminare questi dati. - + Clearing... Eliminazione in corso... - + Select Export Location Scegli dove esportare i dati - + %1.zip %1.zip - - + + Zipped Archives (*.zip) Archivi compressi (*.zip) - + Exporting data. This may take a while... Esportazione dei dati in corso. Potrebbe richiedere un po' di tempo... - + Exporting Esportazione in corso - + Exported Successfully Esportazione completata - + Data was exported successfully. I dati sono stati esportati con successo. - + Export Cancelled Esportazione annullata - + Export was cancelled by the user. L'esportazione è stata annullata dall'utente. - + Export Failed Esportazione fallita - + Ensure you have write permissions on the targeted directory and try again. Assicurati di disporre dei permessi di scrittura nella cartella selezionata e poi riprova. - + Select Import Location Seleziona il file da importare - + Import Warning Attenzione - + All previous data in this directory will be deleted. Are you sure you wish to proceed? Tutti i dati già presenti in questa cartella verranno eliminati. Sei sicuro di voler procedere? - + Importing data. This may take a while... Importazione dei dati in corso. Potrebbe richiedere un po' di tempo... - + Importing Importazione in corso - + Imported Successfully Importazione completata - + Data was imported successfully. I dati sono stati importati con successo. - + Import Cancelled Importazione annullata - + Import was cancelled by the user. L'importazione è stata annullata dall'utente. - + Import Failed Importazione fallita - + Ensure you have read permissions on the targeted directory and try again. Assicurati di disporre dei permessi di lettura nella cartella selezionata e poi riprova. @@ -9895,18 +9895,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed Estrazione mod fallita - + Failed to create temporary directory %1 Impossibile creare la cartella temporanea %1 - + Zip file %1 is empty Il file ZIP %1 è vuoto diff --git a/dist/languages/ja_JP.ts b/dist/languages/ja_JP.ts index c1ab881dde..d8d4723512 100644 --- a/dist/languages/ja_JP.ts +++ b/dist/languages/ja_JP.ts @@ -9208,10 +9208,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9232,210 +9232,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9792,18 +9792,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/ko_KR.ts b/dist/languages/ko_KR.ts index 590a031a80..da2f0dd245 100644 --- a/dist/languages/ko_KR.ts +++ b/dist/languages/ko_KR.ts @@ -4,12 +4,12 @@ About Eden - + Eden에 대해 <html><head/><body><p><span style=" font-size:28pt;">Eden</span></p></body></html> - + <html><head/><body><p><span style=" font-size:28pt;">Eden</span></p></body></html> @@ -26,17 +26,24 @@ li.unchecked::marker { content: "\2610"; } li.checked::marker { content: "\2612"; } </style></head><body style=" font-family:'Noto Sans'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt;">Eden is an experimental open-source emulator for the Nintendo Switch licensed under GPLv3.0+ which is based on the yuzu emulator which ended development back in March 2024. <br /><br />This software should not be used to play games you have not legally obtained.</span></p></body></html> - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +li.unchecked::marker { content: "\2610"; } +li.checked::marker { content: "\2612"; } +</style></head><body style=" font-family:'Noto Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:12pt;">Eden은 GPLv3.0+ 라이선스를 받은 실험적인 오픈 소스 닌텐도 스위치 에뮬레이터로, 2024년 3월에 개발이 종료된 yuzu 에뮬레이터를 기반으로 합니다. <br /><br />이 소프트웨어는 법적으로 획득하지 않은 게임을 플레이하는 데 사용되어서는 안 됩니다.</span></p></body></html> <html><head/><body><p><a href="https://eden-emulator.github.io/"><span style=" text-decoration: underline; color:#039be5;">Website</span></a> | <a href="https://git.eden-emu.dev"><span style=" text-decoration: underline; color:#039be5;">Source Code</span></a> | <a href="https://git.eden-emu.dev/eden-emu/eden/activity/contributors"><span style=" text-decoration: underline; color:#039be5;">Contributors</span></a> | <a href="https://discord.gg/HstXbPch7X"><span style=" text-decoration: underline; color:#039be5;">Discord</span></a> | <a href="https://stt.gg/qKgFEAbH"><span style=" text-decoration: underline; color:#039be5;">Stoat</span></a> | <a href="https://nitter.poast.org/edenemuofficial"><span style=" text-decoration: underline; color:#039be5;">Twitter</span></a> | <a href="https://git.eden-emu.dev/eden-emu/eden/src/branch/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">License</span></a></p></body></html> - + <html><head/><body><p><a href="https://eden-emulator.github.io/"><span style=" text-decoration: underline; color:#039be5;">웹사이트</span></a> | <a href="https://git.eden-emu.dev"><span style=" text-decoration: underline; color:#039be5;">소스 코드</span></a> | <a href="https://git.eden-emu.dev/eden-emu/eden/activity/contributors"><span style=" text-decoration: underline; color:#039be5;">기여자</span></a> | <a href="https://discord.gg/HstXbPch7X"><span style=" text-decoration: underline; color:#039be5;">디스코드</span></a> | <a href="https://stt.gg/qKgFEAbH"><span style=" text-decoration: underline; color:#039be5;">Stoat</span></a> | <a href="https://nitter.poast.org/edenemuofficial"><span style=" text-decoration: underline; color:#039be5;">트위터</span></a> | <a href="https://git.eden-emu.dev/eden-emu/eden/src/branch/master/LICENSE.txt"><span style=" text-decoration: underline; color:#039be5;">라이선스</span></a></p></body></html> <html><head/><body><p><span style=" font-size:7pt;">&quot;Nintendo Switch&quot; is a trademark of Nintendo. Eden is not affiliated with Nintendo in any way.</span></p></body></html> - + <html><head/><body><p><span style=" font-size:7pt;">&quot;닌텐도 스위치&quot;는 닌텐도의 상표이며, Eden은 닌텐도와 어떤 방식으로도 제휴되어 있지 않습니다.</span></p></body></html> @@ -138,7 +145,7 @@ li.checked::marker { content: "\2612"; } Kick - 추방 + 강퇴 @@ -148,12 +155,12 @@ li.checked::marker { content: "\2612"; } Kick Player - 추방된 플레이어 + 강퇴된 플레이어 Are you sure you would like to <b>kick</b> %1? - 정말로 %1을 <b>추방</b>하겠습니까?? + 정말 %1을 <b>강퇴</b>시키겠습니까? @@ -165,9 +172,9 @@ li.checked::marker { content: "\2612"; } Are you sure you would like to <b>kick and ban</b> %1? This would ban both their forum username and their IP address. - %1을 <b>추방</b>하겠습니까? + 정말 %1을 <b>강퇴 및 차단</b>하겠습니까? -이렇게 하면 포럼 사용자 이름과 IP 주소가 모두 금지됩니다. +이렇게 하면 포럼 사용자 이름과 IP 주소 모두 차단됩니다. @@ -232,7 +239,7 @@ This would ban both their forum username and their IP address. <html><head/><body><p><span style=" font-size:10pt;">Should you choose to submit a test case to the </span><a href="https://eden-emulator.github.io/game/"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">eden Compatibility List</span></a><span style=" font-size:10pt;">, The following information will be collected and displayed on the site:</span></p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Hardware Information (CPU / GPU / Operating System)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Which version of eden you are running</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The connected eden account</li></ul></body></html> - + <html><head/><body><p><span style=" font-size:10pt;">만약 </span><a href="https://eden-emulator.github.io/game/"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">eden 호환성 목록</span></a><span style=" font-size:10pt;">에 시험 사례를 제출하기로 선택하면, 다음과 같은 정보가 수집되어 사이트에 표시됩니다:</span></p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">하드웨어 정보(CPU/GPU/운영 체제)</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">사용 중인 eden 버전</li><li style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">연결된 eden 계정</li></ul></body></html> @@ -297,12 +304,12 @@ This would ban both their forum username and their IP address. Major The game has major graphical errors - 주요 게임에 주요 그래픽 오류가 있습니다 + 심각 게임에 심각한 그래픽 오류가 있습니다 Minor The game has minor graphical errors - 마이너 게임에 경미한 그래픽 오류가 있습니다 + 경미 게임에 경미한 그래픽 오류가 있습니다 @@ -317,12 +324,12 @@ This would ban both their forum username and their IP address. Major The game has major audio errors - 메이저 게임에 주요 오디오 오류가 있습니다 + 심각 게임에 심각한 오디오 오류가 있습니다 Minor The game has minor audio errors - 마이너 게임에 사소한 오디오 오류가 있습니다 + 경미 게임에 경미한 오디오 오류가 있습니다 @@ -370,17 +377,17 @@ This would ban both their forum username and their IP address. Amiibo editor - + Amiibo 편집기 Controller configuration - + 컨트롤러 구성 Data erase - + 데이터 삭제 @@ -390,12 +397,12 @@ This would ban both their forum username and their IP address. Net connect - + 망 연결 Player select - + 플레이어 선택 @@ -405,52 +412,52 @@ This would ban both their forum username and their IP address. Mii Edit - + Mii 편집 Online web - + 온라인 웹 Shop - + 숍 Photo viewer - + 사진 뷰어 Offline web - + 오프라인 웹 Login share - + 로그인 공유 Wifi web auth - + Wi-Fi 웹 인증 My page - + 마이페이지 Enable Overlay Applet - + 오버레이 애플릿 활성화 Enables Horizon's built-in overlay applet. Press and hold the home button for 1 second to show it. - + Horizon의 내장 오버레이 애플릿을 활성화합니다. HOME 버튼을 1초 동안 길게 누르면 애플릿이 나타납니다. @@ -470,7 +477,7 @@ This would ban both their forum username and their IP address. Mute audio - + 오디오 음소거 @@ -480,7 +487,7 @@ This would ban both their forum username and their IP address. Mute audio when in background - 백그라운드에서 오디오 음소거 + 백그라운드에서 실행될 때 오디오 음소거 @@ -491,61 +498,66 @@ This would ban both their forum username and their IP address. This option increases CPU emulation thread use from 1 to the maximum of 4. This is mainly a debug option and shouldn't be disabled. - + 이 옵션은 CPU 에뮬레이션 스레드 사용량을 1에서 최대 4까지 증가시킵니다. +이 옵션은 주로 디버그용이므로 비활성화해서는 안 됩니다. Memory Layout - + 메모리 레이아웃 Increases the amount of emulated RAM. Doesn't affect performance/stability but may allow HD texture mods to load. - + 에뮬레이트된 RAM의 용량을 증가시킵니다. +성능/안정성에는 영향을 미치지 않지만 HD 텍스처 모드가 로드될 수 있습니다. Limit Speed Percent - 속도 퍼센트 제한 + 속도 제한 비율 Controls the game's maximum rendering speed, but it's up to each game if it runs faster or not. 200% for a 30 FPS game is 60 FPS, and for a 60 FPS game it will be 120 FPS. Disabling it means unlocking the framerate to the maximum your PC can reach. - + 게임의 최대 렌더링 속도를 제어하지만, 실제로 더 빠르게 실행될지는 각 게임에 따라 다릅니다. +30 FPS 게임에서 200%로 설정하면 60 FPS가 되고, 60 FPS 게임에서는 120 FPS가 됩니다. +이 옵션을 비활성화하면 PC가 도달할 수 있는 최대 프레임률까지 프레임 속도 제한이 해제됩니다. Turbo Speed - + 터보 속도 When the Turbo Speed hotkey is pressed, the speed will be limited to this percentage. - + 터보 속도 단축키를 누르면 속도가 이 비율로 제한됩니다. Slow Speed - + 느린 속도 When the Slow Speed hotkey is pressed, the speed will be limited to this percentage. - + 느린 속도 단축키를 누르면 속도가 이 비율로 제한됩니다. Synchronize Core Speed - + 코어 속도 동기화 Synchronizes CPU core speed with the game's maximum rendering speed to boost FPS without affecting game speed (animations, physics, etc.). Can help reduce stuttering at lower framerates. - + CPU 코어 속도를 게임의 최대 렌더링 속도와 동기화하여 게임 속도(애니메이션, 물리 등)에 영향을 주지 않고 FPS를 향상시킵니다. +낮은 프레임률에서 발생하는 끊김 현상을 줄이는 데 도움될 수 있습니다. @@ -555,56 +567,59 @@ Can help reduce stuttering at lower framerates. Change the accuracy of the emulated CPU (for debugging only). - + 에뮬레이트된 CPU의 정확도를 변경합니다(디버깅용으로만 사용). Backend: - + 백엔드: CPU Overclock - + CPU 오버클럭 Overclocks the emulated CPU to remove some FPS limiters. Weaker CPUs may see reduced performance, and certain games may behave improperly. Use Boost (1700MHz) to run at the Switch's highest native clock, or Fast (2000MHz) to run at 2x clock. - + 에뮬레이트된 CPU를 오버클럭하여 일부 FPS 제한기를 제거합니다. CPU가 약하면 성능이 저하될 수 있으며 특정 게임이 부정확하게 작동할 수 있습니다. +스위치의 최고 네이티브 클럭으로 실행하려면 부스트(1700MHz)를 사용하고, 2배 클럭으로 실행하려면 고속(2000MHz)을 사용하세요. Custom CPU Ticks - + 사용자 지정 CPU 틱 Set a custom value of CPU ticks. Higher values can increase performance, but may cause deadlocks. A range of 77-21000 is recommended. - + CPU 틱 값을 사용자 지정으로 설정합니다. 값이 높을수록 성능이 향상될 수 있지만 교착 상태가 발생할 수 있습니다. 77~21000 범위의 값을 권장합니다. Enable Host MMU Emulation (fastmem) - + 호스트 MMU 에뮬레이션 사용 (빠른 메모리) This optimization speeds up memory accesses by the guest program. Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host's MMU. Disabling this forces all memory accesses to use Software MMU Emulation. - + 이 최적화는 게스트 프로그램의 메모리 접근 속도를 높입니다. +이 옵션을 활성화하면 게스트 메모리 읽기/쓰기가 메모리에서 직접 수행되고 호스트의 MMU를 사용하게 됩니다. +이 옵션을 비활성화하면 모든 메모리 접근에 소프트웨어 MMU 에뮬레이션을 사용하도록 강제됩니다. Unfuse FMA (improve performance on CPUs without FMA) - FMA 분리 (FMA를 지원하지 않는 CPU에서의 성능을 향상시킵니다) + FMA 분리 (FMA를 지원하지 않는 CPU의 성능 향상) This option improves speed by reducing accuracy of fused-multiply-add instructions on CPUs without native FMA support. - + 이 옵션은 네이티브 FMA를 지원하지 않는 CPU의 fused-multiply-add 명령어 정확도를 낮춰 속도를 향상시킵니다. @@ -614,7 +629,7 @@ Disabling this forces all memory accesses to use Software MMU Emulation. This option improves the speed of some approximate floating-point functions by using less accurate native approximations. - + 이 옵션은 정확도가 낮은 네이티브 근사값을 사용하여 일부 근사 부동 소수점 함수의 속도를 향상시킵니다. @@ -2077,12 +2092,12 @@ When a program attempts to open the controller applet, it is immediately closed. Boost (1700MHz) - + 부스트(1700MHz) Fast (2000MHz) - + 고속(2000MHz) @@ -9206,10 +9221,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9230,210 +9245,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9790,18 +9805,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/nb.ts b/dist/languages/nb.ts index 1c876beafc..09e4343217 100644 --- a/dist/languages/nb.ts +++ b/dist/languages/nb.ts @@ -9207,10 +9207,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel Avbryt @@ -9231,210 +9231,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? Er du HELT sikker? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip %1.zip - - + + Zipped Archives (*.zip) Zippede arkiver (*.zip) - + Exporting data. This may take a while... - + Exporting Eksporterer - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed Eksportering mislyktes - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing Importerer - + Imported Successfully Importeringen var vellykket - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed Importering mislyktes - + Ensure you have read permissions on the targeted directory and try again. @@ -9791,18 +9791,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty «%1»-zip-filen er tom diff --git a/dist/languages/nl.ts b/dist/languages/nl.ts index 81d70da92c..f4cd04df28 100644 --- a/dist/languages/nl.ts +++ b/dist/languages/nl.ts @@ -9203,10 +9203,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9227,210 +9227,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9787,18 +9787,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/pl.ts b/dist/languages/pl.ts index ef2078c554..d65dcc0065 100644 --- a/dist/languages/pl.ts +++ b/dist/languages/pl.ts @@ -9306,10 +9306,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel Anuluj @@ -9330,7 +9330,7 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 @@ -9338,204 +9338,204 @@ p, li { white-space: pre-wrap; } %1 - - + + Verifying integrity... Weryfikacja integralności... - - + + Integrity verification succeeded! Weryfikacja integralności zakończona sukcesem! - - + + The operation completed successfully. Operacja zakończona pomyślnie. - - + + Integrity verification failed! Weryfikacja integralności nie powiodła się! - + File contents may be corrupt or missing. Zawartość pliku może być uszkodzona lub brakująca. - + Integrity verification couldn't be performed Nie można było przeprowadzić weryfikacji integralności - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. Instalacja firmware’u została anulowana — firmware może być w złym stanie lub uszkodzony. Nie udało się sprawdzić poprawności zawartości plików. - + Select Dumped Keys Location Wybierz lokalizację zrzutu kluczy - + Decryption Keys install succeeded Instalacja kluczy deszyfrujących powiodła się - + Decryption Keys install failed Instalacja kluczy deszyfrujących nie powiodła się - + Orphaned Profiles Detected! Wykryto osierocone profile! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> MOGĄ WYSTĄPIĆ NIEOCZEKIWANE PROBLEMY, JEŚLI TEGO NIE PRZECZYTASZ!<br>Eden wykrył następujące katalogi zapisów bez przypisanego profilu:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Kliknij „OK”, aby otworzyć folder zapisów i naprawić profile.<br>Wskazówka: skopiuj zawartość największego lub ostatnio modyfikowanego folderu w inne miejsce, usuń wszystkie osierocone profile, a następnie przenieś skopiowaną zawartość do właściwego profilu.<br><br>Nadal masz wątpliwości? Zobacz<a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>tronę pomocy</a>.<br> - + Really clear data? Na pewno wyczyścić dane? - + Important data may be lost! Ważne dane mogą zostać utracone! - + Are you REALLY sure? Czy NA PEWNO chcesz to zrobić? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. Po usunięciu Twoje dane NIE WRÓCĄ! Wykonaj to tylko, jeśli w 100% chcesz usunąć te dane. - + Clearing... Czyszczenie… - + Select Export Location Wybierz lokalizację eksportu - + %1.zip %1.zip - - + + Zipped Archives (*.zip) Archiwa ZIP (.zip) - + Exporting data. This may take a while... Eksportowanie danych. To może chwilę potrwać… - + Exporting Eksportowanie - + Exported Successfully Wyeksportowano pomyślnie - + Data was exported successfully. Dane zostały pomyślnie wyeksportowane. - + Export Cancelled Eksport anulowany - + Export was cancelled by the user. Eksport został anulowany przez użytkownika. - + Export Failed Eksport nie powiódł się - + Ensure you have write permissions on the targeted directory and try again. Upewnij się, że masz uprawnienia zapisu do docelowego katalogu i spróbuj ponownie. - + Select Import Location Wybierz lokalizację importu - + Import Warning Ostrzeżenie dotyczące importu - + All previous data in this directory will be deleted. Are you sure you wish to proceed? Wszystkie dotychczasowe dane w tym katalogu zostaną usunięte. Czy na pewno chcesz kontynuować? - + Importing data. This may take a while... Importowanie danych. To może chwilę potrwać… - + Importing Importowanie - + Imported Successfully Zaimportowano pomyślnie - + Data was imported successfully. Dane zostały pomyślnie zaimportowane. - + Import Cancelled Import anulowany - + Import was cancelled by the user. Import został anulowany przez użytkownika. - + Import Failed Import nie powiódł się - + Ensure you have read permissions on the targeted directory and try again. Upewnij się, że masz uprawnienia odczytu do docelowego katalogu i spróbuj ponownie. @@ -9897,18 +9897,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/pt_BR.ts b/dist/languages/pt_BR.ts index 1bb88abafc..26cfd9d0dc 100644 --- a/dist/languages/pt_BR.ts +++ b/dist/languages/pt_BR.ts @@ -9279,10 +9279,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9303,210 +9303,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9865,18 +9865,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 Falha ao criar um diretório temporário %1 - + Zip file %1 is empty diff --git a/dist/languages/pt_PT.ts b/dist/languages/pt_PT.ts index 1e535c5e92..a0b4b1fce9 100644 --- a/dist/languages/pt_PT.ts +++ b/dist/languages/pt_PT.ts @@ -9206,10 +9206,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9230,210 +9230,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9790,18 +9790,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/ru_RU.ts b/dist/languages/ru_RU.ts index 063804860b..571baa18ec 100644 --- a/dist/languages/ru_RU.ts +++ b/dist/languages/ru_RU.ts @@ -9322,10 +9322,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel Отмена @@ -9346,7 +9346,7 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 @@ -9355,204 +9355,204 @@ p, li { white-space: pre-wrap; } %1 - - + + Verifying integrity... Проверка целостности... - - + + Integrity verification succeeded! Проверка целостности прошла успешно! - - + + The operation completed successfully. Операция выполнена успешно. - - + + Integrity verification failed! Проверка целостности не удалась! - + File contents may be corrupt or missing. Содержимое файла может быть повреждено или отсутствовать. - + Integrity verification couldn't be performed Проверка целостности не может быть выполнена - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. Установка прошивки отменена, прошивка может быть повреждена. Содержимое файла не удалось проверить на корректность. - + Select Dumped Keys Location Выберите местоположение дампнутых ключей - + Decryption Keys install succeeded Установка ключей дешифровки прошла успешно. - + Decryption Keys install failed Ошибка установки ключей дешифровки - + Orphaned Profiles Detected! Обнаружены «сиротские» профили! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> МОГУТ ПРОИЗОЙТИ НЕПРЕДВИДЕННЫЕ ПРОБЛЕМЫ, ЕСЛИ ВЫ НЕ ПРОЧИТАЕТЕ ЭТО!<br>Eden обнаружил следующие папки сохранений без привязанного профиля:<br>%1<br><br>Найдены следующие корректные профили:<br>%2<br><br>Нажмите «OK», чтобы открыть папку сохранений и исправить профили.<br>Совет: скопируйте содержимое самой большой или последней измененной папки в другое место, удалите все «сиротские» профили и переместите скопированные данные в правильный профиль.<br><br>Если есть вопросы, прочитайте <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>справку</a>.<br> - + Really clear data? Действительно очистить данные? - + Important data may be lost! Важные данные могут быть потеряны! - + Are you REALLY sure? Вы уверены? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. Данные будут безвозвратно потеряны после удаления! Делайте это только если вы абсолютно уверены, что хотите их удалить. - + Clearing... Очистка... - + Select Export Location Выберите папку для экспорта - + %1.zip %1.zip - - + + Zipped Archives (*.zip) Архивы ZIP (*.zip) - + Exporting data. This may take a while... Идет экспорт данных. Это может занять некоторое время... - + Exporting Экспорт - + Exported Successfully Экспорт выполнен успешно - + Data was exported successfully. Данные успешно экспортированы. - + Export Cancelled Экспорт отменен - + Export was cancelled by the user. Экспорт был отменен пользователем. - + Export Failed Не удалось экспортировать - + Ensure you have write permissions on the targeted directory and try again. Проверьте, есть ли права на запись в выбранную папку, и повторите попытку. - + Select Import Location Выберите папку для импорта - + Import Warning Предупреждение при импорте - + All previous data in this directory will be deleted. Are you sure you wish to proceed? Все существующие данные в этой папке будут удалены. Вы уверены, что хотите продолжить? - + Importing data. This may take a while... Идет импорт данных. Это может занять некоторое время... - + Importing Импорт - + Imported Successfully Импорт успешно выполнен - + Data was imported successfully. Данные успешно импортированы. - + Import Cancelled Импорт отменен - + Import was cancelled by the user. Импорт был отменен пользователем. - + Import Failed Не удалось импортировать - + Ensure you have read permissions on the targeted directory and try again. Проверьте, есть ли права на чтение в выбранной папке, и повторите попытку. @@ -9916,18 +9916,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed Ошибка извлечения мода - + Failed to create temporary directory %1 Не удалось создать временную папку %1 - + Zip file %1 is empty ZIP-файл %1 пуст diff --git a/dist/languages/sv.ts b/dist/languages/sv.ts index 3865e56ee0..c7a96cc11b 100644 --- a/dist/languages/sv.ts +++ b/dist/languages/sv.ts @@ -9323,10 +9323,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel Avbryt @@ -9347,7 +9347,7 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 @@ -9356,204 +9356,204 @@ p, li { white-space: pre-wrap; } %1 - - + + Verifying integrity... Verifierar integritet... - - + + Integrity verification succeeded! Integritetsverifieringen lyckades! - - + + The operation completed successfully. Operationen slutfördes utan problem. - - + + Integrity verification failed! Integritetsverifieringen misslyckades! - + File contents may be corrupt or missing. Filens innehåll kan vara skadat eller saknas. - + Integrity verification couldn't be performed Integritetsverifiering kunde inte utföras - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. Firmwareinstallationen avbruten, firmware kan vara i dåligt skick eller skadad. Filens innehåll kunde inte kontrolleras för giltighet. - + Select Dumped Keys Location Välj plats för dumpade nycklar - + Decryption Keys install succeeded Installation av avkrypteringsnycklar lyckades - + Decryption Keys install failed Installationen av avkrypteringsnycklar misslyckades - + Orphaned Profiles Detected! Föräldralösa profiler upptäcktes! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> OVÄNTADE PROBLEM KAN UPPSTÅ OM DU INTE LÄSER DETTA! <br>Eden har upptäckt följande sparningskataloger utan bifogade profiler:<br>%1<br><br>Följande profiler är giltiga:<br>%2<br><br>Klicka på ”OK” för att öppna din sparningsmapp och fixa dina profiler.<br>Tips: kopiera innehållet i den största eller senast ändrade mappen till en annan plats, ta bort alla övergivna profiler och flytta det kopierade innehållet till den giltiga profilen.<br><br>Fortfarande förvirrad? Se hjälpsidan<a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>.<br> - + Really clear data? Verkligen tömma data? - + Important data may be lost! Viktig data kan gå förlorad! - + Are you REALLY sure? Är du VERKLIGEN säker? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. När dina data har raderats kan de INTE återställas! Gör detta endast om du är 100% säker på att du vill radera dessa data. - + Clearing... Tömmer... - + Select Export Location Välj exportplats - + %1.zip %1.zip - - + + Zipped Archives (*.zip) Zippade arkiv (*.zip) - + Exporting data. This may take a while... Exporterar data. Detta kan ta en stund... - + Exporting Exporterar - + Exported Successfully Exporten lyckades - + Data was exported successfully. Data har exporterats. - + Export Cancelled Exporten avbröts - + Export was cancelled by the user. Exporten avbröts av användaren. - + Export Failed Exporten misslyckades - + Ensure you have write permissions on the targeted directory and try again. Kontrollera att du har skrivbehörighet till den aktuella katalogen och försök igen. - + Select Import Location Välj importplats - + Import Warning Importvarning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? Alla tidigare data i denna katalog kommer att raderas. Är du säker på att du vill fortsätta? - + Importing data. This may take a while... Importerar data. Detta kan ta en stund... - + Importing Importerar - + Imported Successfully Importen lyckades - + Data was imported successfully. Data har importerats. - + Import Cancelled Importen avbröts - + Import was cancelled by the user. Importen avbröts av användaren. - + Import Failed Importen misslyckades - + Ensure you have read permissions on the targeted directory and try again. Kontrollera att du har läsbehörighet till den aktuella katalogen och försök igen. @@ -9917,18 +9917,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed Mod-extrahering misslyckades - + Failed to create temporary directory %1 Det gick inte att skapa den tillfälliga katalogen %1 - + Zip file %1 is empty Zip-filen %1 är tom diff --git a/dist/languages/tr_TR.ts b/dist/languages/tr_TR.ts index 5cc62a47d8..08dedb182c 100644 --- a/dist/languages/tr_TR.ts +++ b/dist/languages/tr_TR.ts @@ -9234,10 +9234,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9258,210 +9258,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9818,18 +9818,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/uk.ts b/dist/languages/uk.ts index fe0651bdb1..d7089147a7 100644 --- a/dist/languages/uk.ts +++ b/dist/languages/uk.ts @@ -9324,10 +9324,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel Скасувати @@ -9348,7 +9348,7 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 @@ -9357,204 +9357,204 @@ p, li { white-space: pre-wrap; } %1 - - + + Verifying integrity... Перевірка цілісності... - - + + Integrity verification succeeded! Перевірка цілісності успішна! - - + + The operation completed successfully. Операцію успішно завершено. - - + + Integrity verification failed! Не вдалося перевірити цілісність! - + File contents may be corrupt or missing. Файли вмісту можуть бути пошкоджені або відсутні. - + Integrity verification couldn't be performed Неможливо виконати перевірку цілісності - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. Встановлення прошивки скасовано. Можливо, прошивка в поганому стані або пошкоджена. Неможливо перевірити на дійсність файли вмісту. - + Select Dumped Keys Location Виберіть розатшування дампу ключів - + Decryption Keys install succeeded Ключі дешифрування успішно встановлено - + Decryption Keys install failed Не вдалося встановити ключі дешифрування - + Orphaned Profiles Detected! Виявлено покинуті профілі! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> ЯКЩО ВИ ЦЕ НЕ ПРОЧИТАЄТЕ, МОЖУТЬ СТАТИСЯ НЕОЧІКУВАНІ ПОГАНІ РЕЧІ!<br>Eden виявив такі теки збережень без прикріпленого профілю:<br>%1<br><br>Є такі дійсні профілі:<br>%2<br><br>Натисніть «ОК», щоб відкрити теку збережень і полагодити свої профілі.<br>Порада: скопіюйте у будь-яке інше місце вміст найбільшої теки, у якій нещодавно були зміни, видаліть профілі, що лишилися та перемістіть скопійований вміст до провильного профілю.<br><br>Досі не розумієте, що робити? Перегляньте <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>сторінку допомоги</a>.<br> - + Really clear data? Дійсно очистити дані? - + Important data may be lost! Може бути втрачено важливі дані! - + Are you REALLY sure? Ви ДІЙСНО впевнені? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. Після видалення ваші дані буде НЕМОЖЛИВО повернути! Виконуйте цю дію, лише якщо ви на 100% упевнені, що хочете видалити ці дані. - + Clearing... Очищення... - + Select Export Location Виберіть розташування для експортування - + %1.zip %1.zip - - + + Zipped Archives (*.zip) Zip-архіви (*.zip) - + Exporting data. This may take a while... Експортування даних. Це може тривати певний час... - + Exporting Експортування - + Exported Successfully Успішно експортовано - + Data was exported successfully. Дані успішно експортовано. - + Export Cancelled Експортування скасовано - + Export was cancelled by the user. Експортування скасовано користувачем. - + Export Failed Не вдалося експортувати - + Ensure you have write permissions on the targeted directory and try again. Запевніться, що у вас є дозволи на записування до вказаної теки й спробуйте знову. - + Select Import Location Виберіть розташування для імпортування - + Import Warning Попередження щодо імпортування - + All previous data in this directory will be deleted. Are you sure you wish to proceed? Усі попередні в цій теці будуть видалені. Ви впевнені, що хочете продовжити? - + Importing data. This may take a while... Імпортування даних. Це може тривати певний час... - + Importing Імпортування - + Imported Successfully Успішно імпортовано - + Data was imported successfully. Дані успішно імпортовано. - + Import Cancelled Імпортування скасовано - + Import was cancelled by the user. Імпортування скасовано користувачем. - + Import Failed Не вдалося імпортувати - + Ensure you have read permissions on the targeted directory and try again. Запевніться, що у вас є дозволи на читання зі вказаної теки й спробуйте знову. @@ -9918,18 +9918,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed Не вдалося видобути мод - + Failed to create temporary directory %1 Не вдалося створити тимчасову теку %1 - + Zip file %1 is empty Zip-файл %1 порожній diff --git a/dist/languages/vi.ts b/dist/languages/vi.ts index 5cbda3c24f..e09ec68d7b 100644 --- a/dist/languages/vi.ts +++ b/dist/languages/vi.ts @@ -9206,10 +9206,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9230,210 +9230,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9790,18 +9790,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/vi_VN.ts b/dist/languages/vi_VN.ts index 8fa5494c73..4ee726cf82 100644 --- a/dist/languages/vi_VN.ts +++ b/dist/languages/vi_VN.ts @@ -9206,10 +9206,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9230,210 +9230,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9790,18 +9790,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/dist/languages/zh_CN.ts b/dist/languages/zh_CN.ts index aa5cda0fcc..bfc28e8926 100644 --- a/dist/languages/zh_CN.ts +++ b/dist/languages/zh_CN.ts @@ -9299,10 +9299,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel 取消 @@ -9323,7 +9323,7 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 @@ -9332,204 +9332,204 @@ p, li { white-space: pre-wrap; } %1 - - + + Verifying integrity... 正在验证完整性... - - + + Integrity verification succeeded! 完整性验证成功! - - + + The operation completed successfully. 操作成功完成。 - - + + Integrity verification failed! 完整性验证失败! - + File contents may be corrupt or missing. 文件内容可能缺失或已损坏。 - + Integrity verification couldn't be performed 无法执行完整性验证 - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. 固件安装失败。固件可能处于异常状态或已损坏,无法验证文件内容的有效性。 - + Select Dumped Keys Location 选择导出的密钥文件位置 - + Decryption Keys install succeeded 密钥文件安装成功 - + Decryption Keys install failed 密钥文件安装失败 - + Orphaned Profiles Detected! 检测到孤立的配置文件! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> 如果您不阅读此内容,可能会发生意想不到的糟糕情况!<br>Eden 检测到以下存档目录没有附加的配置文件:<br>%1<br><br>下列配置是有效的:<br>%2<br><br>点击“确定”以打开您的存档文件夹并修复配置文件。<br>提示: 将最大或最近修改的文件夹内容复制到其他地方,删除所有孤立的配置文件,然后将复制的内容移到正确的配置文件中。<br><br>还是感到疑惑? 请查看 <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>帮助页</a>。<br> - + Really clear data? 确实要清除数据吗? - + Important data may be lost! 可能会丢失重要的数据! - + Are you REALLY sure? 您真的确定吗? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. 在删除后,您将无法找回数据! 仅在您 100% 确认要删除此数据时才这样做。 - + Clearing... 正在清除... - + Select Export Location 选择导出位置 - + %1.zip %1.zip - - + + Zipped Archives (*.zip) 压缩档案 (*.zip) - + Exporting data. This may take a while... 正在导出数据。这可能需要一些时间... - + Exporting 正在导出 - + Exported Successfully 导出成功 - + Data was exported successfully. 数据已成功导出。 - + Export Cancelled 导出已被取消 - + Export was cancelled by the user. 导出已被用户取消。 - + Export Failed 导出失败 - + Ensure you have write permissions on the targeted directory and try again. 请确认您是否具有目标目录的写入权限然后再次尝试。 - + Select Import Location 选择导入位置 - + Import Warning 导入警告 - + All previous data in this directory will be deleted. Are you sure you wish to proceed? 此目录中的所有先前数据将被删除。您确定要继续吗? - + Importing data. This may take a while... 正在导入数据。这需要一些时间... - + Importing 正在导入 - + Imported Successfully 导入成功 - + Data was imported successfully. 数据已导入成功。 - + Import Cancelled 导入已被取消 - + Import was cancelled by the user. 导入已被用户取消。 - + Import Failed 导入失败 - + Ensure you have read permissions on the targeted directory and try again. 请确认是否您具有目标目录的读取权限然后再次尝试。 @@ -9891,18 +9891,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed 模组提取失败 - + Failed to create temporary directory %1 未能创建临时 %1 目录 - + Zip file %1 is empty 压缩文件 %1 是空的。 diff --git a/dist/languages/zh_TW.ts b/dist/languages/zh_TW.ts index b09469591b..ce80998e5d 100644 --- a/dist/languages/zh_TW.ts +++ b/dist/languages/zh_TW.ts @@ -9232,10 +9232,10 @@ p, li { white-space: pre-wrap; } - - - - + + + + Cancel @@ -9256,210 +9256,210 @@ p, li { white-space: pre-wrap; } - + Verification failed for the following files: %1 - - + + Verifying integrity... - - + + Integrity verification succeeded! - - + + The operation completed successfully. - - + + Integrity verification failed! - + File contents may be corrupt or missing. - + Integrity verification couldn't be performed - + Firmware installation cancelled, firmware may be in a bad state or corrupted. File contents could not be checked for validity. - + Select Dumped Keys Location - + Decryption Keys install succeeded - + Decryption Keys install failed - + Orphaned Profiles Detected! - + UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>Eden has detected the following save directories with no attached profile:<br>%1<br><br>The following profiles are valid:<br>%2<br><br>Click "OK" to open your save folder and fix up your profiles.<br>Hint: copy the contents of the largest or last-modified folder elsewhere, delete all orphaned profiles, and move your copied contents to the good profile.<br><br>Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br> - + Really clear data? - + Important data may be lost! - + Are you REALLY sure? - + Once deleted, your data will NOT come back! Only do this if you're 100% sure you want to delete this data. - + Clearing... - + Select Export Location - + %1.zip - - + + Zipped Archives (*.zip) - + Exporting data. This may take a while... - + Exporting - + Exported Successfully - + Data was exported successfully. - + Export Cancelled - + Export was cancelled by the user. - + Export Failed - + Ensure you have write permissions on the targeted directory and try again. - + Select Import Location - + Import Warning - + All previous data in this directory will be deleted. Are you sure you wish to proceed? - + Importing data. This may take a while... - + Importing - + Imported Successfully - + Data was imported successfully. - + Import Cancelled - + Import was cancelled by the user. - + Import Failed - + Ensure you have read permissions on the targeted directory and try again. @@ -9816,18 +9816,18 @@ Most mods are RomFS mods, but patches (.pchtxt) are typically ExeFS mods. - - + + Mod Extract Failed - + Failed to create temporary directory %1 - + Zip file %1 is empty diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml index 1abf996752..167ffe6ff1 100644 --- a/src/android/app/src/main/res/values-es/strings.xml +++ b/src/android/app/src/main/res/values-es/strings.xml @@ -489,6 +489,8 @@ Activar el historial del búfer Permite el acceso al estado del búfer anterior. Esta opción puede mejorar la calidad de renderizado y la consistencia en el rendimiento de algunos juegos. Búferes de vértices optimizados + Permite la optimización del enlace del búfer de vértices para un mejor rendimiento. Requiere controladores Mesa 26.0+ Turnip/ controladores QCOM. Fallará con controladores Turnip más antiguos (versión 25.3 o inferior). + Hacks Tiempo rápido de la GPU @@ -500,6 +502,7 @@ Emular BGR565 Soluciona problemas con colores invertidos en juegos, artefactos o sombras extrañas. Activar la pasada de reescalado heredada + Permite el manejo de versiones anteriores para el paso de configuración de reescalado para juegos mediante el uso de una ruta de reescalado rápida. Usar sombreadores asíncronos Compila los sombreadores de forma asíncrona. Esto puede reducir los tirones, pero también puede introducir errores gráficos. Ajustes de desentrelazado de la GPU @@ -518,8 +521,10 @@ Extensiones Estado dinámico extendido + Controla la cantidad de características que se pueden usar en ExtendedDynamicState (EDS). Un valor más alto permitirá reducir la cantidad de compilaciones de canalización basadas en el estado dinámico compatible con el controlador. Desactivado Estado dinámico de entrada de vértices + La activación de esta función permite un manejo más flexible de la entrada de vértices, lo que podría reducir el tiempo de compilación de la canalización en vértices/búfer. Muestreo de sombreado Permite que el sombreador de fragmentos se ejecute por muestra en un fragmento multimuestreado, en lugar de una sola vez por fragmento. Mejora la calidad de los gráficos a coste de algo de rendimiento. diff --git a/src/android/app/src/main/res/values-zh-rCN/strings.xml b/src/android/app/src/main/res/values-zh-rCN/strings.xml index bedc53dc43..e9ea040ffb 100644 --- a/src/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/android/app/src/main/res/values-zh-rCN/strings.xml @@ -66,6 +66,8 @@ 显示当前功耗和电池剩余容量 显示着色器编译信息 显示当前正在编译的着色器数量 + 管线工作线程 + 管理用于构建 Vulkan 管线的核心数量,数值越高则管线编译性能越好,但温度也会随之升高。 叠加层位置 选择叠加层在屏幕上显示的位置 左上 @@ -473,14 +475,18 @@ 磁盘着色器缓存 将生成的着色器缓存于磁盘中并进行读取,以减少卡顿。 强制最大时钟 (仅限 Adreno) - 强制 GPU 以最大时钟运行 (仍被温控限制)。 + 强制 GPU 以最大时钟运行 (温控依然生效)。 GPU 异步模拟 + 此技巧可通过异步运行 GPU 模拟来提升性能,但在执行与时序相关的操作时,可能引入图形问题和增加崩溃概率。 异步呈现 + 此技巧通过将图形呈现移至独立的 CPU 线程来提升性能,但可能会引入图形显示问题。 启用反应性刷新 通过牺牲性能来提高某些游戏的渲染精度。 启用缓冲区历史 启用对先前缓冲区状态的访问。此选项可在某些游戏中提升渲染质量并保持性能的一致性。 优化顶点缓冲区 + 启用经过优化的顶点缓冲区绑定以提升性能。需要 Mesa 26.0 及以上版本的 Turnip 或 QCOM 驱动程序。若使用较旧版本的 Turnip 驱动 (25.3 及以下版本) 则会导致崩溃。 + Hacks GPU 超频频率 @@ -491,6 +497,8 @@ 减少《塞尔达传说:智慧的再现》(Adreno A6XX - A7XX/ Turnip)中的 bloom 模糊,并移除《Burnout》中的 bloom 效果。警告:可能会导致在其他游戏中出现图形异常。 模拟 BGR565 修复了游戏中的颜色反转以及出现的异常画面瑕疵或奇怪阴影问题 + 启用旧版缩放处理 + 启用通过使用快速缩放路径,来为游戏提供缩放配置处理的传统处理方式 使用异步着色器 异步编译着色器。这可能会减少卡顿,但也可能会导致图形错误。 GPU 还原设置 @@ -509,8 +517,10 @@ 扩展 扩展动态状态 + 控制扩展动态状态 (EDS) 可使用的功能数目。较高的数值将允许根据驱动程序支持的动态状态来减少管线编译的次数。 已禁用 顶点输入动态状态 + 启用此功能可实现更灵活的顶点输入处理,可能减少顶点/缓冲区的管线编译时间。 采样着色 允许片段着色器在多采样片段中每个样本执行一次,而不是每个片段执行一次。以提高性能为代价改善图形质量。 From 50df88106ef5adef4b3a84d2b40ddafd336e7915 Mon Sep 17 00:00:00 2001 From: crueter Date: Sun, 17 May 2026 22:54:32 +0200 Subject: [PATCH 45/58] [externals] Remove httplib minimum version spec (#3967) For some Godforsaken reason it uses SameMinorVersion. Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3967 Reviewed-by: Lizzie Reviewed-by: MaranBr --- externals/cpmfile.json | 1 - 1 file changed, 1 deletion(-) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 0f8d34230c..0302f11c1e 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -30,7 +30,6 @@ "tag": "v%VERSION%", "hash": "5efa8140aadffe105dcf39935b732476e95755f6c7473ada3d0b64df2bc02c557633ae3948a25b45e1cf67e89a3ff6329fb30362e4ac033b9a1d1e453aa2eded", "git_version": "0.37.0", - "version": "0.18.7", "find_args": "MODULE GLOBAL", "patches": [ "0001-mingw.patch", From ca6bb3ae1d2805e92aef30a99abb12ec9d6d795e Mon Sep 17 00:00:00 2001 From: crueter Date: Sun, 17 May 2026 23:44:57 +0200 Subject: [PATCH 46/58] [cmake, dist] Update udev rule to act on all joysticks, and add install option (#3968) This is needed for gyro access. Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3968 Reviewed-by: Lizzie Reviewed-by: MaranBr --- CMakeLists.txt | 16 ++++++++++++++-- dist/72-eden-input.rules | 8 ++++++++ dist/72-yuzu-input.rules | 19 ------------------- docs/Options.md | 3 +++ 4 files changed, 25 insertions(+), 21 deletions(-) create mode 100644 dist/72-eden-input.rules delete mode 100644 dist/72-yuzu-input.rules diff --git a/CMakeLists.txt b/CMakeLists.txt index 32e873f009..cbb4a25a2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,8 +190,7 @@ if(MSVC) $<$:$<$:/${libflag}d>> $<$:$<$:/${libflag}>> $<$:$<$:/${libflag}>> - $<$:$<$:/${libflag}>> - ) + $<$:$<$:/${libflag}>>) endif() # TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system @@ -230,6 +229,10 @@ cmake_dependent_option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}") +# Install udev rules on Linux (mainly for gyros) +# Only acts on joysticks and nothing else. +cmake_dependent_option(YUZU_INSTALL_UDEV_RULES "Install udev rules for gyro access" OFF "PLATFORM_LINUX" OFF) + option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON) option(YUZU_LEGACY "Apply patches that improve compatibility with older GPUs (e.g. Snapdragon 865) at the cost of performance" OFF) @@ -730,6 +733,8 @@ endif() # https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html # https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html # https://www.freedesktop.org/software/appstream/docs/ + +# TODO: Icon/install handling n such should be put into dist/CMakeLists.txt if(ENABLE_QT AND UNIX AND NOT APPLE) install(FILES "dist/dev.eden_emu.eden.desktop" DESTINATION "share/applications") @@ -742,3 +747,10 @@ if(ENABLE_QT AND UNIX AND NOT APPLE) install(FILES "dist/dev.eden_emu.eden.metainfo.xml" DESTINATION "share/metainfo") endif() + +if (YUZU_INSTALL_UDEV_RULES) + include(GNUInstallDirs) + + install(FILES "dist/72-eden-input.rules" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/udev/rules.d") +endif() diff --git a/dist/72-eden-input.rules b/dist/72-eden-input.rules new file mode 100644 index 0000000000..b84ed200a3 --- /dev/null +++ b/dist/72-eden-input.rules @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2023 yuzu Emulator Project +# SPDX-License-Identifier: GPL-2.0-or-later + +# Allow systemd-logind to manage user access to hidraw with this file +# On most systems, this file should be installed to /etc/udev/rules.d/72-eden-input.rules +# Consult your distro if this is not the case + +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ENV{ID_INPUT_JOYSTICK}=="1", MODE="0660", TAG+="uaccess" diff --git a/dist/72-yuzu-input.rules b/dist/72-yuzu-input.rules deleted file mode 100644 index d64f8b28d7..0000000000 --- a/dist/72-yuzu-input.rules +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-FileCopyrightText: 2023 yuzu Emulator Project -# SPDX-License-Identifier: GPL-2.0-or-later - -# Allow systemd-logind to manage user access to hidraw with this file -# On most systems, this file should be installed to /etc/udev/rules.d/72-yuzu-input.rules -# Consult your distro if this is not the case - -# Switch Pro Controller (USB/Bluetooth) -KERNEL=="hidraw*", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="2009", MODE="0660", TAG+="uaccess" -KERNEL=="hidraw*", KERNELS=="*057e:2009*", MODE="0660", TAG+="uaccess" - -# Joy-Con L (Bluetooth) -KERNEL=="hidraw*", KERNELS=="*057e:2006*", MODE="0660", TAG+="uaccess" - -# Joy-Con R (Bluetooth) -KERNEL=="hidraw*", KERNELS=="*057e:2007*", MODE="0660", TAG+="uaccess" - -# Joy-Con Charging Grip (USB) -KERNEL=="hidraw*", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="200e", MODE="0660", TAG+="uaccess" diff --git a/docs/Options.md b/docs/Options.md index 3eb6effe92..adf8127d41 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -44,6 +44,9 @@ These options control dependencies. - 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 +- `YUZU_INSTALL_UDEV_RULES` (OFF) Install udev rules to enable hidraw access + - Needed for gyroscopes + - Only available on Linux ### Flavors From 9a7ca3aca450b6c87dc9568df9972abef70c414d Mon Sep 17 00:00:00 2001 From: lizzie Date: Mon, 18 May 2026 02:09:33 +0200 Subject: [PATCH 47/58] [dynarmic] fix NetBSD context.h compile error (#3966) On NetBSD it stupidly aligns the stack acounting for the amd64 redzone. This isn't... required, to put it lightly. Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3966 Reviewed-by: CamilleLaVey Reviewed-by: MaranBr --- .../backend/exception_handler_posix.cpp | 12 ++-- src/dynarmic/src/dynarmic/common/context.h | 60 +++++++++++-------- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp index 50d552aa0e..224559133a 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp @@ -121,15 +121,15 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { #if defined(ARCHITECTURE_x86_64) { std::shared_lock guard(sig_handler->code_block_infos_mutex); - if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_RIP); iter != sig_handler->code_block_infos.end()) { - FakeCall fc = iter->second.cb(CTX_RIP); - CTX_RSP -= sizeof(u64); - *std::bit_cast(CTX_RSP) = fc.ret_rip; - CTX_RIP = fc.call_rip; + if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_PC); iter != sig_handler->code_block_infos.end()) { + FakeCall fc = iter->second.cb(CTX_PC); + CTX_SP -= sizeof(u64); + *std::bit_cast(CTX_SP) = fc.ret_rip; + CTX_PC = fc.call_rip; return; } } - fmt::print(stderr, "Unhandled {} at rip {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_RIP); + fmt::print(stderr, "Unhandled {} at rip {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC); #elif defined(ARCHITECTURE_arm64) { std::shared_lock guard(sig_handler->code_block_infos_mutex); diff --git a/src/dynarmic/src/dynarmic/common/context.h b/src/dynarmic/src/dynarmic/common/context.h index e849c9861b..db7af8e0ae 100644 --- a/src/dynarmic/src/dynarmic/common/context.h +++ b/src/dynarmic/src/dynarmic/common/context.h @@ -51,7 +51,25 @@ # endif #endif -#ifdef ARCHITECTURE_arm64 +// Some OSes define generic helper macros for all architectures +#if defined(__NetBSD__) +// NetBSD always has useful macros for everything don't they? +// Basically this special path means that for every arch that NetBSD supports +// it atleast has the macro for _UC_MACHINE defined, thus it will be avoided on the +// other macro branches! +// https://github.com/NetBSD/src/blob/trunk/sys/arch/powerpc/include/mcontext.h +// https://github.com/NetBSD/src/blob/trunk/sys/arch/mips/include/mcontext.h +# define CTX_PC (_UC_MACHINE_PC(ucontext)) +// NetBSD defines a redzone for SP but we don't require nor want that +// ((uc)->uc_mcontext.__gregs[_REG_RSP] - 128) -> this is not desirable due to calcs +#if defined(ARCHITECTURE_x86_64) +# define CTX_SP (mctx.__gregs[_REG_RSP]) +#else +# define CTX_SP (_UC_MACHINE_SP(ucontext)) +#endif +#endif + +#if defined(ARCHITECTURE_arm64) # if defined(__APPLE__) # define CTX_PC (mctx->__ss.__pc) # define CTX_SP (mctx->__ss.__sp) @@ -76,9 +94,7 @@ # define CTX_LR (mctx.mc_gpregs.gp_lr) # define CTX_X(i) (mctx.mc_gpregs.gp_x[i]) # define CTX_Q(i) (mctx.mc_fpregs.fp_q[i]) -# elif defined(__NetBSD__) -# define CTX_PC (mctx.mc_gpregs.gp_elr) -# define CTX_SP (mctx.mc_gpregs.gp_sp) +# elif defined(__NetBSD__) // SP + PC defined above # define CTX_LR (mctx.mc_gpregs.gp_lr) # define CTX_X(i) (mctx.mc_gpregs.gp_x[i]) # define CTX_Q(i) (mctx.mc_fpregs.fp_q[i]) @@ -92,35 +108,29 @@ # else # error "unknown platform" # endif -#elif defined(__NetBSD__) -// NetBSD always has useful macros for everything don't they? -// Basically this special path means that for every arch that NetBSD supports -// it atleast has the macro for _UC_MACHINE defined, thus it will be avoided on the -// other macro branches! -// https://github.com/NetBSD/src/blob/trunk/sys/arch/powerpc/include/mcontext.h -// https://github.com/NetBSD/src/blob/trunk/sys/arch/mips/include/mcontext.h -# define CTX_PC (_UC_MACHINE_PC(ucontext)) -# define CTX_SP (_UC_MACHINE_SP(ucontext)) #elif defined(ARCHITECTURE_x86_64) # if defined(__APPLE__) -# define CTX_RIP (mctx->__ss.__rip) -# define CTX_RSP (mctx->__ss.__rsp) +# define CTX_PC (mctx->__ss.__rip) +# define CTX_SP (mctx->__ss.__rsp) # elif defined(__linux__) -# define CTX_RIP (mctx.gregs[REG_RIP]) -# define CTX_RSP (mctx.gregs[REG_RSP]) +# define CTX_PC (mctx.gregs[REG_RIP]) +# define CTX_SP (mctx.gregs[REG_RSP]) # elif defined(__FreeBSD__) -# define CTX_RIP (mctx.mc_rip) -# define CTX_RSP (mctx.mc_rsp) +# define CTX_PC (mctx.mc_rip) +# define CTX_SP (mctx.mc_rsp) # elif defined(__OpenBSD__) // https://github.com/openbsd/src/blob/master/sys/arch/x86_64/include/signal.h -# define CTX_RIP (ucontext->sc_rip) -# define CTX_RSP (ucontext->sc_rsp) +# define CTX_PC (ucontext->sc_rip) +# define CTX_SP (ucontext->sc_rsp) # elif defined(__sun__) -# define CTX_RIP (mctx.gregs[REG_RIP]) -# define CTX_RSP (mctx.gregs[REG_RSP]) +# define CTX_PC (mctx.gregs[REG_RIP]) +# define CTX_SP (mctx.gregs[REG_RSP]) # elif defined(__DragonFly__) -# define CTX_RIP (mctx.mc_rip) -# define CTX_RSP (mctx.mc_rsp) +# define CTX_PC (mctx.mc_rip) +# define CTX_SP (mctx.mc_rsp) +# elif defined(__managarm__) +# define CTX_PC (mctx.__pollution(gregs)[REG_RIP]) +# define CTX_SP (mctx.__pollution(gregs)[REG_RSP]) # else # error "unknown platform" # endif From 02521882e788223f357af8e777eb322735afbf1d Mon Sep 17 00:00:00 2001 From: Marcin Serwin Date: Mon, 18 May 2026 17:31:52 +0200 Subject: [PATCH 48/58] [dynarmic] drop Xeon Phi features from tests (#3978) xbyak 7.37 dropped support for them, see and . Signed-off-by: Marcin Serwin Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3978 Reviewed-by: crueter Reviewed-by: Lizzie --- src/dynarmic/tests/x64_cpu_info.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/dynarmic/tests/x64_cpu_info.cpp b/src/dynarmic/tests/x64_cpu_info.cpp index a33d8c013f..8837e64ae0 100644 --- a/src/dynarmic/tests/x64_cpu_info.cpp +++ b/src/dynarmic/tests/x64_cpu_info.cpp @@ -39,8 +39,6 @@ TEST_CASE("Host CPU supports", "[a64]") { X(tAMX_TILE), X(tAVX), X(tAVX2), - X(tAVX512_4FMAPS), - X(tAVX512_4VNNIW), X(tAVX512_BF16), X(tAVX512_BITALG), X(tAVX512_FP16), @@ -53,10 +51,8 @@ TEST_CASE("Host CPU supports", "[a64]") { X(tAVX512BW), X(tAVX512CD), X(tAVX512DQ), - X(tAVX512ER), X(tAVX512F), X(tAVX512IFMA), - X(tAVX512PF), X(tAVX512VBMI), X(tAVX512VL), X(tAVX_VNNI), @@ -84,7 +80,6 @@ TEST_CASE("Host CPU supports", "[a64]") { X(tPCLMULQDQ), X(tPOPCNT), X(tPREFETCHW), - X(tPREFETCHWT1), X(tRDRAND), X(tRDSEED), X(tRDTSCP), From ad2e1cc554ecd363ae1412b66d537464bba001e7 Mon Sep 17 00:00:00 2001 From: Kaydax Date: Mon, 18 May 2026 19:07:41 +0200 Subject: [PATCH 49/58] [externals] Update to SDL3 (#3952) Since the launch of the steam controller I think it's only best to push towards updating to SDL3 allowing for a wider range of controller support I went ahead and started on getting it working. Everything here should be functional, I've personally tested it all on Arch Linux. Still untested on windows, so looking for feedback on that Any feedback and help would be appreciated! Main changes: - Bump everything to SDL3 - Handle SDL3 audio and input - Add steam controller support, including HD Rumble - Improved battery reporting via the status icon by using real % rather than state alone Co-authored-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3952 Reviewed-by: crueter Reviewed-by: MaranBr Reviewed-by: Lizzie --- CMakeLists.txt | 13 +- docs/Caveats.md | 3 +- docs/Deps.md | 42 +- docs/Options.md | 6 +- docs/user/Architectures.md | 2 +- docs/user/CommandLine.md | 4 +- externals/CMakeLists.txt | 28 +- externals/cpmfile.json | 31 +- shell.nix | 2 +- src/audio_core/CMakeLists.txt | 8 +- .../sink/{sdl2_sink.cpp => sdl3_sink.cpp} | 128 +++-- .../sink/{sdl2_sink.h => sdl3_sink.h} | 2 +- src/audio_core/sink/sink_details.cpp | 12 +- src/common/settings_enums.h | 6 +- src/input_common/CMakeLists.txt | 4 +- src/input_common/drivers/joycon.h | 5 +- src/input_common/drivers/sdl_driver.cpp | 482 ++++++++++++------ src/input_common/drivers/sdl_driver.h | 14 +- .../helpers/joycon_protocol/joycon_types.h | 5 +- src/input_common/main.cpp | 22 +- src/yuzu/CMakeLists.txt | 2 +- src/yuzu/main_window.cpp | 2 +- src/yuzu_cmd/CMakeLists.txt | 18 +- .../emu_window/emu_window_sdl2_vk.cpp | 98 ---- ...mu_window_sdl2.cpp => emu_window_sdl3.cpp} | 139 ++--- .../{emu_window_sdl2.h => emu_window_sdl3.h} | 11 +- ...dow_sdl2_gl.cpp => emu_window_sdl3_gl.cpp} | 41 +- ..._window_sdl2_gl.h => emu_window_sdl3_gl.h} | 14 +- ...sdl2_null.cpp => emu_window_sdl3_null.cpp} | 22 +- ...dow_sdl2_null.h => emu_window_sdl3_null.h} | 11 +- .../emu_window/emu_window_sdl3_vk.cpp | 99 ++++ ..._window_sdl2_vk.h => emu_window_sdl3_vk.h} | 11 +- src/yuzu_cmd/sdl_config.cpp | 2 +- src/yuzu_cmd/yuzu.cpp | 16 +- 34 files changed, 768 insertions(+), 537 deletions(-) rename src/audio_core/sink/{sdl2_sink.cpp => sdl3_sink.cpp} (62%) rename src/audio_core/sink/{sdl2_sink.h => sdl3_sink.h} (97%) delete mode 100644 src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp rename src/yuzu_cmd/emu_window/{emu_window_sdl2.cpp => emu_window_sdl3.cpp} (68%) rename src/yuzu_cmd/emu_window/{emu_window_sdl2.h => emu_window_sdl3.h} (92%) rename src/yuzu_cmd/emu_window/{emu_window_sdl2_gl.cpp => emu_window_sdl3_gl.cpp} (79%) rename src/yuzu_cmd/emu_window/{emu_window_sdl2_gl.h => emu_window_sdl3_gl.h} (70%) rename src/yuzu_cmd/emu_window/{emu_window_sdl2_null.cpp => emu_window_sdl3_null.cpp} (67%) rename src/yuzu_cmd/emu_window/{emu_window_sdl2_null.h => emu_window_sdl3_null.h} (58%) create mode 100644 src/yuzu_cmd/emu_window/emu_window_sdl3_vk.cpp rename src/yuzu_cmd/emu_window/{emu_window_sdl2_vk.h => emu_window_sdl3_vk.h} (59%) diff --git a/CMakeLists.txt b/CMakeLists.txt index cbb4a25a2d..f828f20bd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,13 +119,13 @@ if (YUZU_STATIC_BUILD) set(QuaZip-Qt6_FORCE_BUNDLED ON) set(YUZU_USE_BUNDLED_FFMPEG ON) - set(YUZU_USE_BUNDLED_SDL2 ON) + set(YUZU_USE_BUNDLED_SDL3 ON) set(YUZU_USE_BUNDLED_OPENSSL ON) set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF) elseif(APPLE) set(YUZU_USE_BUNDLED_FFMPEG ON) - set(YUZU_USE_BUNDLED_SDL2 ON) + set(YUZU_USE_BUNDLED_SDL3 ON) set(YUZU_USE_BUNDLED_OPENSSL ON) # these libs do not properly provide static libs/let you do it with cmake @@ -194,8 +194,7 @@ if(MSVC) endif() # 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 "NOT MSVC;NOT ANDROID" OFF) -cmake_dependent_option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "NOT ANDROID" OFF) +cmake_dependent_option(YUZU_USE_BUNDLED_SDL3 "Download bundled SDL3 build" "${MSVC}" "NOT ANDROID" OFF) option(ENABLE_CUBEB "Enables the cubeb audio backend" ON) @@ -361,10 +360,6 @@ if (CXX_GCC OR CXX_CLANG) endif() endif() -# Other presets, e.g. steamdeck -# TODO(crueter): Just have every Linux/Windows use old sdl2 -set(YUZU_SYSTEM_PROFILE "generic" CACHE STRING "CMake and Externals profile to use. One of: generic, steamdeck") - # Configure C++ standard # =========================== @@ -562,7 +557,7 @@ if (NOT YUZU_STATIC_ROOM) endif() if (NOT ANDROID) - find_package(SDL2) + find_package(SDL3) endif() if (USE_DISCORD_PRESENCE) diff --git a/docs/Caveats.md b/docs/Caveats.md index 8c752cf79d..fb86437737 100644 --- a/docs/Caveats.md +++ b/docs/Caveats.md @@ -65,14 +65,13 @@ export LIBGL_ALWAYS_SOFTWARE=1 ``` - Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`). -- If using OpenIndiana, due to a bug in SDL2's CMake configuration, audio driver defaults to SunOS ``, which does not exist on OpenIndiana. Using external or bundled SDL2 may solve this. - System OpenSSL generally does not work. Instead, use `-DYUZU_USE_BUNDLED_OPENSSL=ON` to use a bundled static OpenSSL, or build a system dependency from source. ## OmniOS Install `developer/gcc14` on OmniOS using pkgsrc. -Since so many dependencies are missing on `OmniOS`, you may wish to use `-DCPMUTIL_FORCE_BUNDLED=ON -DYUZU_USE_EXTERNAL_SDL2=ON` +Since so many dependencies are missing on `OmniOS`, you may wish to use `-DCPMUTIL_FORCE_BUNDLED=ON` For OmniOS you are required to build glslang yourself: ```sh diff --git a/docs/Deps.md b/docs/Deps.md index 83ac0ac799..2c1c3589df 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -47,7 +47,7 @@ If you are on **Windows** and building with **MSVC** or **clang-cl**, you may go The following are handled by Eden's externals: * [FFmpeg](https://ffmpeg.org/) (should use `-DYUZU_USE_EXTERNAL_FFMPEG=ON`) -* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL2=ON` OR `-DYUZU_USE_BUNDLED_SDL2=ON` to reduce compile time) +* [SDL3](https://www.libsdl.org/download-2.0.php) 3.2.10+ (Use `-DYUZU_USE_BUNDLED_SDL2=ON` to reduce compile time) All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available (UNIX-like only): @@ -123,7 +123,7 @@ sudo emerge -a \ dev-util/spirv-tools dev-util/spirv-headers dev-util/vulkan-headers \ 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 \ + media-libs/VulkanMemoryAllocator media-libs/libsdl3 media-libs/cubeb \ net-libs/enet \ sys-libs/zlib \ dev-cpp/nlohmann_json dev-cpp/simpleini dev-cpp/cpp-httplib dev-cpp/cpp-jwt \ @@ -142,7 +142,8 @@ Required USE flags: * `dev-qt/qtbase network concurrent dbus gui widgets` * `dev-libs/quazip qt6` -* `media-libs/libsdl2 haptic joystick sound video` +* `media-libs/libsdl3 haptic joystick sound video` + * Adding `X vulkan udev opengl` is recommended but not required * `dev-cpp/cpp-httplib ssl` [Caveats](./Caveats.md#gentoo-linux) @@ -153,7 +154,7 @@ Required USE flags: Arch Linux ```sh -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 +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 sdl3 zlib zstd zip unzip vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers ``` * Building with QT Web Engine requires `qt6-webengine` as well. @@ -166,10 +167,10 @@ sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glsl Ubuntu, Debian, Mint Linux ```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 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 +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 libsdl3-dev libopus-dev libasound2t64 vulkan-utility-libraries-dev ``` -* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. +* Ubuntu 26.04, Linux Mint 22.3, or Debian 13 or later is required. * To enable QT Web Engine, add `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake.
@@ -190,13 +191,13 @@ AlmaLinux (use `YUZU_USE_CPM=ON`): sudo dnf install epel-release dnf-utils # (run rpmfusion installation afterwards) # vvv - This will work for most systems -sudo dnf install autoconf cmake libtool libudev cmake gcc gcc-c++ qt6-qtbase-devel zlib-devel openssl-devel boost SDL2 ffmpeg-devel libdrm glslang jq patch +sudo dnf install autoconf cmake libtool libudev cmake gcc gcc-c++ qt6-qtbase-devel zlib-devel openssl-devel boost SDL3 ffmpeg-devel libdrm glslang jq patch # Qt6 private GUI must be taken from CRB repos sudo dnf config-manager --enable crb sudo dnf install qt6-qtbase-private-devel ``` -For systems like OpenEuler or derivates, don't forget to also install: `SDL2-devel pkg-config fmt-dev nlohmann-json-dev`. +For systems like OpenEuler or derivates, don't forget to also install: `SDL3-devel pkg-config fmt-dev nlohmann-json-dev`. * [RPM Fusion](https://rpmfusion.org/Configuration) is required for `ffmpeg-devel` * Fedora 32 or later is required. @@ -213,7 +214,7 @@ 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 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 +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 sdl3-dev zstd-dev vulkan-utility-libraries spirv-tools-dev openssl-dev nlohmann-json lz4-dev opus-dev jq patch ``` @@ -221,7 +222,7 @@ apk add g++ git cmake make mesa-dev qt6-qtbase-dev qt6-qtbase-private-dev libqua Void Linux ```sh -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 +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 SDL3-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? @@ -242,7 +243,7 @@ If you're going for a pure build (i.e no downloaded deps), use `-DYUZU_USE_CPM=O Install dependencies from **[Homebrew](https://brew.sh/)** ```sh -brew install autoconf automake boost ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zstd cmake Catch2 molten-vk vulkan-loader spirv-tools +brew install autoconf automake boost ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl3 speexdsp zlib zstd cmake Catch2 molten-vk vulkan-loader spirv-tools ``` If you are compiling on Intel Mac, or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` with `/usr/local`. @@ -259,7 +260,7 @@ brew install molten-vk
FreeBSD -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` +As root run: `pkg install devel/cmake sdl3 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. @@ -270,8 +271,9 @@ If using FreeBSD 12 or prior, use `devel/pkg-config` instead. NetBSD For NetBSD +10.1: + ```sh -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 frozen +pkgin install git cmake boost fmtlib SDL3 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 frozen ``` [Caveats](./Caveats.md#netbsd). @@ -282,7 +284,7 @@ pkgin install git cmake boost fmtlib SDL2 catch2 libjwt spirv-headers spirv-tool ```sh pkg_add -u -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 quazip-qt6 +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 sdl3 libusb1-1.0.29 quazip-qt6 ``` [Caveats](./Caveats.md#openbsd). @@ -292,7 +294,7 @@ pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gm DragonFlyBSD ```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 qt6-charts 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 sdl3 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). @@ -302,7 +304,7 @@ pkg install gcc14 git cmake unzip nasm autoconf bash pkgconf ffmpeg glslang gmak OpenIndiana ```sh -sudo pkg install git cmake qt6 boost glslang libzip library/lz4 libusb-1 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt +sudo pkg install git cmake qt6 boost glslang libzip library/lz4 libusb-1 nlohmann-json openssl opus sdl3 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt ``` [Caveats](./Caveats.md#openindiana). @@ -326,7 +328,7 @@ sudo pkgin install git cmake autoconf build-essential libusb-1 nasm gcc13 ```sh BASE="git make autoconf libtool automake-wrapper jq patch" -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" +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 SDL3" # Either x86_64 or clang-aarch64 (Windows on ARM) packages="$BASE" for pkg in $MINGW; do @@ -352,7 +354,7 @@ pacman -Syuu --needed --noconfirm $packages HaikuOS ```sh -pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.90_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 cubeb_devel simpleini quazip_qt6_devel +pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.90_devel vulkan_devel qt6_base_devel qt6_declarative_devel libsdl3_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt5_devel qt6_5compat_devel glslang qt6_devel qt6_charts_devel cubeb_devel simpleini quazip_qt6_devel ``` [Caveats](./Caveats.md#haikuos). @@ -363,9 +365,11 @@ pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel b ```sh sudo pkg update -sudo pkg install git cmake ffmpeg6 sdl2 zlib llvm18 +sudo pkg install git cmake ffmpeg6 zlib llvm18 ``` +RedoxOS currently does not support SDL3. You will have to compile it yourself and pray. + [Caveats](./Caveats.md#redoxos).
diff --git a/docs/Options.md b/docs/Options.md index adf8127d41..bd353b16ca 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -29,8 +29,7 @@ These options control dependencies. - `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 +- `YUZU_USE_BUNDLED_SDL3` (ON for MSVC) Download a prebuilt SDL3 ### Miscellaneous @@ -63,7 +62,7 @@ These options control executables and build flavors. **Desktop only**: -- `YUZU_CMD` (ON) Compile the SDL2 frontend (eden-cli) +- `YUZU_CMD` (ON) Compile the SDL-based 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 @@ -99,5 +98,6 @@ The following options were a part of Eden at one point, but have since been reti - `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`. +- `YUZU_USE_EXTERNAL_SDL` - This is now handled automatically. It was included even after CPM for purposes that have not applied for a very long time. See `src/dynarmic/CMakeLists.txt` for additional options--usually, these don't need changed diff --git a/docs/user/Architectures.md b/docs/user/Architectures.md index 45f9e85c4f..a03dbc0da8 100644 --- a/docs/user/Architectures.md +++ b/docs/user/Architectures.md @@ -40,7 +40,7 @@ Windows/riscv64 doesn't exist, and may never (until corporate greed no longer co Android/riscv64 is interesting. While support for it may be added if and when RISC-V phones/handhelds ever go mainstream, arm64 devices will always be preferred due to NCE. -Only Fedora/riscv64 has been tested, but in theory, every riscv64 distribution that has *at least* the standard build tools, Qt, FFmpeg, and SDL2 should work. +Only Fedora/riscv64 has been tested, but in theory, every riscv64 distribution that has *at least* the standard build tools, Qt, FFmpeg, and SDL3 should work. ## Other diff --git a/docs/user/CommandLine.md b/docs/user/CommandLine.md index cd98d88b19..41f8d3d711 100644 --- a/docs/user/CommandLine.md +++ b/docs/user/CommandLine.md @@ -1,8 +1,9 @@ # User Handbook - Command Line -There are two main applications, an SDL2 based app (`eden-cli`) and a Qt based app (`eden`); both accept command line arguments. +There are two main applications, an SDL-based app (`eden-cli`) and a Qt based app (`eden`); both accept command line arguments. ## eden + - `./eden `: Running with a single argument and nothing else, will make the emulator look for the given file and load it, this behaviour is similar to `eden-cli`; allows dragging and dropping games into the application. - `-g `: Alternate way to specify what to load, overrides. However let it be noted that arguments that use `-` will be treated as options/ignored, if your game, for some reason, starts with `-`, in order to safely handle it you may need to specify it as an argument. - `-f`: Use fullscreen. @@ -12,6 +13,7 @@ There are two main applications, an SDL2 based app (`eden-cli`) and a Qt based a - `-setup`: Launch setup applet. ## eden-cli + - `--debug/-d`: Enter debug mode, allow gdb stub at port `1234` - `--config/-c`: Specify alternate configuration file. - `--fullscreen/-f`: Set fullscreen. diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index e230f709fa..72dafa4704 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -136,8 +136,7 @@ if(ENABLE_CUBEB) endif() if (NOT ANDROID) - if (YUZU_USE_EXTERNAL_SDL2) - message(STATUS "Using SDL2 from externals.") + if (YUZU_USE_BUNDLED_SDL3) if (NOT WIN32) # Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers # Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095) @@ -158,21 +157,26 @@ if (NOT ANDROID) set(SDL_FILE ON) endif() - if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck") - set(SDL_PIPEWIRE OFF) # build errors out with this on - AddJsonPackage("sdl2_steamdeck") - else() - AddJsonPackage("sdl2_generic") - endif() - elseif (YUZU_USE_BUNDLED_SDL2) - message(STATUS "Using bundled SDL2") + AddJsonPackage(sdl3) + else() + message(STATUS "Using bundled SDL3") if (PLATFORM_FREEBSD) set(BUILD_SHARED_LIBS ON) endif() - AddJsonPackage(sdl2) + AddJsonPackage(sdl3-ci) endif() - find_package(SDL2 2.26.4 REQUIRED) + # Normalize SDL3 link target across package variants. + # Some SDL3 packages export only SDL3::SDL3-shared or SDL3::SDL3-static. + if (NOT TARGET SDL3::SDL3) + if (TARGET SDL3::SDL3-shared) + add_library(SDL3::SDL3 ALIAS SDL3::SDL3-shared) + elseif (TARGET SDL3::SDL3-static) + add_library(SDL3::SDL3 ALIAS SDL3::SDL3-static) + else() + message(FATAL_ERROR "SDL3 package found, but no usable SDL3 target was exported") + endif() + endif() endif() set(BUILD_SHARED_LIBS OFF) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 0302f11c1e..4e9356cb83 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -122,13 +122,13 @@ "BUNDLE_SPEEX ON" ] }, - "sdl2": { + "sdl3-ci": { "ci": true, - "package": "SDL2", - "name": "SDL2", - "repo": "crueter-ci/SDL2", - "version": "2.32.10-3c28e8ecc0", - "min_version": "2.26.4" + "package": "SDL3", + "name": "SDL3", + "repo": "crueter-ci/SDL3", + "version": "3.4.8-d57c3b685c", + "min_version": "3.2.10" }, "catch2": { "package": "Catch2", @@ -156,22 +156,13 @@ "find_args": "MODULE", "git_version": "4.25" }, - "sdl2_generic": { - "package": "SDL2", + "sdl3": { + "package": "SDL3", "repo": "libsdl-org/SDL", "tag": "release-%VERSION%", - "hash": "d5622d6bb7266f7942a7b8ad43e8a22524893bf0c2ea1af91204838d9b78d32768843f6faa248757427b8404b8c6443776d4afa6b672cd8571a4e0c03a829383", - "bundled": true, - "git_version": "2.32.10", - "skip_updates": true - }, - "sdl2_steamdeck": { - "package": "SDL2", - "repo": "libsdl-org/SDL", - "sha": "cc016b0046", - "hash": "b8d9873446cdb922387471df9968e078714683046674ef0d0edddf8e25da65a539a3bae83d635496b970237f90b07b36a69f8d7855d450de59311d6d6e8c3dbc", - "bundled": true, - "skip_updates": "true" + "hash": "df5a323af7ac366661a3c0e887969c72584d232f3cc211419d59b0487b620b6b2859d4549c9e8df002ee489290062e466fcfddf7edc0872a37b1f2845e81c0f3", + "git_version": "3.4.8", + "version": "3.2.10" }, "moltenvk": { "repo": "V380-Ori/Ryujinx.MoltenVK", diff --git a/shell.nix b/shell.nix index d8257b88d9..5023cc88a3 100644 --- a/shell.nix +++ b/shell.nix @@ -16,7 +16,7 @@ pkgs.mkShellNoCC { qt6.qtbase qt6.qtmultimedia qt6.qtwayland qt6.qttools qt6.qtwebengine qt6.qt5compat # eden-cli - SDL2 + SDL3 # optional components discord-rpc gamemode ]; diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index e31fd2c5b9..4d0b130afc 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -247,11 +247,11 @@ if(ANDROID) target_compile_definitions(audio_core PUBLIC HAVE_OBOE) else() target_sources(audio_core PRIVATE - sink/sdl2_sink.cpp - sink/sdl2_sink.h) + sink/sdl3_sink.cpp + sink/sdl3_sink.h) - target_link_libraries(audio_core PRIVATE SDL2::SDL2) - target_compile_definitions(audio_core PRIVATE HAVE_SDL2) + target_link_libraries(audio_core PRIVATE SDL3::SDL3) + target_compile_definitions(audio_core PRIVATE HAVE_SDL3) endif() create_target_directory_groups(audio_core) diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl3_sink.cpp similarity index 62% rename from src/audio_core/sink/sdl2_sink.cpp rename to src/audio_core/sink/sdl3_sink.cpp index b016bf2222..990b62deb5 100644 --- a/src/audio_core/sink/sdl2_sink.cpp +++ b/src/audio_core/sink/sdl3_sink.cpp @@ -7,16 +7,40 @@ #include #include -#include +#include #include "audio_core/common/common.h" -#include "audio_core/sink/sdl2_sink.h" +#include "audio_core/sink/sdl3_sink.h" #include "audio_core/sink/sink_stream.h" #include "common/logging.h" #include "common/scope_exit.h" #include "core/core.h" namespace AudioCore::Sink { + +namespace { +SDL_AudioDeviceID FindAudioDeviceByName(const std::string& device_name, bool capture) { + int device_count = 0; + SDL_AudioDeviceID* devices = capture ? SDL_GetAudioRecordingDevices(&device_count) + : SDL_GetAudioPlaybackDevices(&device_count); + if (devices == nullptr) { + return capture ? SDL_AUDIO_DEVICE_DEFAULT_RECORDING : SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK; + } + + SDL_AudioDeviceID selected = capture ? SDL_AUDIO_DEVICE_DEFAULT_RECORDING + : SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK; + for (int i = 0; i < device_count; ++i) { + const char* current_name = SDL_GetAudioDeviceName(devices[i]); + if (current_name != nullptr && device_name == current_name) { + selected = devices[i]; + break; + } + } + SDL_free(devices); + return selected; +} +} // Anonymous namespace + /** * SDL sink stream, responsible for sinking samples to hardware. */ @@ -39,13 +63,10 @@ public: system_channels = system_channels_; device_channels = device_channels_; - SDL_AudioSpec spec; + SDL_AudioSpec spec{}; spec.freq = TargetSampleRate; spec.channels = static_cast(device_channels); - spec.format = AUDIO_S16SYS; - spec.samples = TargetSampleCount * 2; - spec.callback = &SDLSinkStream::DataCallback; - spec.userdata = this; + spec.format = SDL_AUDIO_S16; std::string device_name{output_device}; bool capture{false}; @@ -54,22 +75,28 @@ public: capture = true; } - SDL_AudioSpec obtained; - if (device_name.empty()) { - device = SDL_OpenAudioDevice(nullptr, capture, &spec, &obtained, false); - } else { - device = SDL_OpenAudioDevice(device_name.c_str(), capture, &spec, &obtained, false); - } + const SDL_AudioDeviceID audio_device = + device_name.empty() ? (capture ? SDL_AUDIO_DEVICE_DEFAULT_RECORDING + : SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK) + : FindAudioDeviceByName(device_name, capture); - if (device == 0) { + stream = SDL_OpenAudioDeviceStream(audio_device, &spec, &SDLSinkStream::DataCallback, + this); + + if (stream == nullptr) { LOG_CRITICAL(Audio_Sink, "Error opening SDL audio device: {}", SDL_GetError()); return; } + SDL_AudioSpec stream_in{}; + SDL_AudioSpec stream_out{}; + static_cast(SDL_GetAudioStreamFormat(stream, &stream_in, &stream_out)); + LOG_INFO(Service_Audio, "Opening SDL stream {} with: rate {} channels {} (system channels {}) " - " samples {}", - device, obtained.freq, obtained.channels, system_channels, obtained.samples); + " format {}", + static_cast(stream), stream_out.freq, stream_out.channels, + system_channels, static_cast(stream_out.format)); } /** @@ -84,13 +111,14 @@ public: * Finalize the sink stream. */ void Finalize() override { - if (device == 0) { + if (stream == nullptr) { return; } Stop(); - SDL_ClearQueuedAudio(device); - SDL_CloseAudioDevice(device); + SDL_ClearAudioStream(stream); + SDL_DestroyAudioStream(stream); + stream = nullptr; } /** @@ -100,23 +128,23 @@ public: * Default false. */ void Start(bool resume = false) override { - if (device == 0 || !paused) { + if (stream == nullptr || !paused) { return; } paused = false; - SDL_PauseAudioDevice(device, 0); + static_cast(SDL_ResumeAudioStreamDevice(stream)); } /** * Stop the sink stream. */ void Stop() override { - if (device == 0 || paused) { + if (stream == nullptr || paused) { return; } SignalPause(); - SDL_PauseAudioDevice(device, 1); + static_cast(SDL_PauseAudioStreamDevice(stream)); } private: @@ -128,7 +156,8 @@ private: * @param stream - Buffer of samples to be filled or read. * @param len - Length of the stream in bytes. */ - static void DataCallback(void* userdata, Uint8* stream, int len) { + static void DataCallback(void* userdata, SDL_AudioStream* stream, int additional_amount, + int total_amount) { auto* impl = static_cast(userdata); if (!impl) { @@ -137,25 +166,46 @@ private: const std::size_t num_channels = impl->GetDeviceChannels(); const std::size_t frame_size = num_channels; - const std::size_t num_frames{len / num_channels / sizeof(s16)}; if (impl->type == StreamType::In) { - std::span input_buffer{reinterpret_cast(stream), - num_frames * frame_size}; + const int bytes_available = SDL_GetAudioStreamAvailable(stream); + if (bytes_available <= 0) { + return; + } + + std::vector input(bytes_available / static_cast(sizeof(s16))); + const int bytes_read = SDL_GetAudioStreamData(stream, input.data(), bytes_available); + if (bytes_read <= 0) { + return; + } + + const std::size_t num_frames = + static_cast(bytes_read) / sizeof(s16) / frame_size; + std::span input_buffer{input.data(), + static_cast(bytes_read) / sizeof(s16)}; impl->ProcessAudioIn(input_buffer, num_frames); } else { - std::span output_buffer{reinterpret_cast(stream), num_frames * frame_size}; + if (additional_amount <= 0 && total_amount <= 0) { + return; + } + + const int bytes_requested = additional_amount > 0 ? additional_amount : total_amount; + std::vector output(bytes_requested / static_cast(sizeof(s16))); + const std::size_t num_frames = + static_cast(bytes_requested) / sizeof(s16) / frame_size; + std::span output_buffer{output.data(), output.size()}; impl->ProcessAudioOutAndRender(output_buffer, num_frames); + static_cast(SDL_PutAudioStreamData(stream, output.data(), bytes_requested)); } } - /// SDL device id of the opened input/output device - SDL_AudioDeviceID device{}; + /// SDL stream attached to an opened input/output device + SDL_AudioStream* stream{}; }; SDLSink::SDLSink(std::string_view target_device_name) { if (!SDL_WasInit(SDL_INIT_AUDIO)) { - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { + if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) { LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError()); return; } @@ -218,18 +268,26 @@ std::vector ListSDLSinkDevices(bool capture) { std::vector device_list; if (!SDL_WasInit(SDL_INIT_AUDIO)) { - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { + if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) { LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError()); return {}; } } - const int device_count = SDL_GetNumAudioDevices(capture); + int device_count = 0; + SDL_AudioDeviceID* devices = + capture ? SDL_GetAudioRecordingDevices(&device_count) + : SDL_GetAudioPlaybackDevices(&device_count); + if (devices == nullptr) { + return device_list; + } + for (int i = 0; i < device_count; ++i) { - if (const char* name = SDL_GetAudioDeviceName(i, capture)) { + if (const char* name = SDL_GetAudioDeviceName(devices[i])) { device_list.emplace_back(name); } } + SDL_free(devices); return device_list; } @@ -242,7 +300,7 @@ u32 GetSDLLatency() { // REVERTED back to 3833 - Below function IsSDLSuitable() removed, reverting to GetSDLLatency() above. - DIABLO 3 FIX /* bool IsSDLSuitable() { -#if !defined(HAVE_SDL2) +#if !defined(HAVE_SDL3) return false; #else // Check SDL can init diff --git a/src/audio_core/sink/sdl2_sink.h b/src/audio_core/sink/sdl3_sink.h similarity index 97% rename from src/audio_core/sink/sdl2_sink.h rename to src/audio_core/sink/sdl3_sink.h index 19ea32595f..d0f4586f53 100644 --- a/src/audio_core/sink/sdl2_sink.h +++ b/src/audio_core/sink/sdl3_sink.h @@ -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: Copyright 2018 yuzu Emulator Project diff --git a/src/audio_core/sink/sink_details.cpp b/src/audio_core/sink/sink_details.cpp index 4420560d22..1b737eb12e 100644 --- a/src/audio_core/sink/sink_details.cpp +++ b/src/audio_core/sink/sink_details.cpp @@ -16,8 +16,8 @@ #ifdef HAVE_CUBEB #include "audio_core/sink/cubeb_sink.h" #endif -#ifdef HAVE_SDL2 -#include "audio_core/sink/sdl2_sink.h" +#ifdef HAVE_SDL3 +#include "audio_core/sink/sdl3_sink.h" #endif #include "audio_core/sink/null_sink.h" #include "common/logging.h" @@ -71,9 +71,9 @@ constexpr SinkDetails sink_details[] = { &GetCubebLatency, }, #endif -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 SinkDetails{ - Settings::AudioEngine::Sdl2, + Settings::AudioEngine::Sdl3, [](std::string_view device_id) -> std::unique_ptr { return std::make_unique(device_id); }, @@ -115,10 +115,10 @@ const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) { // BEGIN REINTRODUCED FROM 3833 - REPLACED CODE BLOCK ABOVE - DIABLO 3 FIX // Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which // causes audio issues, in that case go with SDL. -#if defined(HAVE_CUBEB) && defined(HAVE_SDL2) +#if defined(HAVE_CUBEB) && defined(HAVE_SDL3) iter = find_backend(Settings::AudioEngine::Cubeb); if (iter->latency() > TargetSampleCount * 3) { - iter = find_backend(Settings::AudioEngine::Sdl2); + iter = find_backend(Settings::AudioEngine::Sdl3); } #else iter = std::begin(sink_details); diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 638be4127f..9a406e432b 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -92,11 +92,13 @@ struct EnumMetadata { // AudioEngine must be specified discretely due to having existing but slightly different // canonicalizations // TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id -enum class AudioEngine : u32 { Auto, Cubeb, Sdl2, Null, Oboe, }; +enum class AudioEngine : u32 { Auto, Cubeb, Sdl3, Null, Oboe, }; template<> inline std::vector> EnumMetadata::Canonicalizations() { return { - {"auto", AudioEngine::Auto}, {"cubeb", AudioEngine::Cubeb}, {"sdl2", AudioEngine::Sdl2}, + {"auto", AudioEngine::Auto}, + {"cubeb", AudioEngine::Cubeb}, + {"sdl3", AudioEngine::Sdl3}, {"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe}, }; } diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index 406ee967b0..91dd8558ab 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt @@ -79,8 +79,8 @@ else() helpers/joycon_protocol/rumble.cpp helpers/joycon_protocol/rumble.h) - target_link_libraries(input_common PRIVATE SDL2::SDL2) - target_compile_definitions(input_common PRIVATE HAVE_SDL2) + target_link_libraries(input_common PRIVATE SDL3::SDL3) + target_compile_definitions(input_common PRIVATE HAVE_SDL3) endif() if (ENABLE_LIBUSB) diff --git a/src/input_common/drivers/joycon.h b/src/input_common/drivers/joycon.h index 112e970e15..820c4b2eaa 100644 --- a/src/input_common/drivers/joycon.h +++ b/src/input_common/drivers/joycon.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -6,7 +9,7 @@ #include #include #include -#include +#include #include "input_common/input_engine.h" diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 948f650fb1..ad854110ef 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -15,29 +15,79 @@ namespace InputCommon { namespace { Common::UUID GetGUID(SDL_Joystick* joystick) { - const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + const SDL_GUID guid = SDL_GetJoystickGUID(joystick); std::array data{}; std::memcpy(data.data(), guid.data, sizeof(data)); // Clear controller name crc std::memset(data.data() + 2, 0, sizeof(u16)); return Common::UUID{data}; } + +using GamepadBindings = std::vector; + +SDL_GamepadBinding EmptyBinding() { + SDL_GamepadBinding binding{}; + binding.input_type = SDL_GAMEPAD_BINDTYPE_NONE; + return binding; +} + +GamepadBindings GetBindings(SDL_Gamepad* controller) { + if (controller == nullptr) { + return {}; + } + + int binding_count = 0; + SDL_GamepadBinding** bindings = SDL_GetGamepadBindings(controller, &binding_count); + if (bindings == nullptr) { + return {}; + } + + GamepadBindings cached_bindings{}; + cached_bindings.reserve(static_cast(binding_count)); + for (int i = 0; i < binding_count; ++i) { + if (const auto* current = bindings[i]) { + cached_bindings.emplace_back(*current); + } + } + SDL_free(bindings); + return cached_bindings; +} + +template +SDL_GamepadBinding FindBinding(const GamepadBindings& bindings, Predicate matches) { + const auto it = std::find_if(bindings.begin(), bindings.end(), matches); + return it != bindings.end() ? *it : EmptyBinding(); +} + +SDL_GamepadBinding GetBindingForButton(const GamepadBindings& bindings, SDL_GamepadButton button) { + return FindBinding(bindings, [button](const SDL_GamepadBinding& current) { + return current.output_type == SDL_GAMEPAD_BINDTYPE_BUTTON && + current.output.button == static_cast(button); + }); +} + +SDL_GamepadBinding GetBindingForAxis(const GamepadBindings& bindings, SDL_GamepadAxis axis) { + return FindBinding(bindings, [axis](const SDL_GamepadBinding& current) { + return current.output_type == SDL_GAMEPAD_BINDTYPE_AXIS && + current.output.axis.axis == static_cast(axis); + }); +} } // Anonymous namespace -static int SDLEventWatcher(void* user_data, SDL_Event* event) { +static bool SDLEventWatcher(void* user_data, SDL_Event* event) { auto* const sdl_state = static_cast(user_data); sdl_state->HandleGameControllerEvent(*event); - return 0; + return true; } class SDLJoystick { public: SDLJoystick(Common::UUID guid_, int port_, SDL_Joystick* joystick, - SDL_GameController* game_controller) - : guid{guid_}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, - sdl_controller{game_controller, &SDL_GameControllerClose} { + SDL_Gamepad* game_controller) + : guid{guid_}, port{port_}, sdl_joystick{joystick, &SDL_CloseJoystick}, + sdl_controller{game_controller, &SDL_CloseGamepad} { EnableMotion(); } @@ -45,30 +95,49 @@ public: if (!sdl_controller) { return; } - SDL_GameController* controller = sdl_controller.get(); + SDL_Gamepad* controller = sdl_controller.get(); if (HasMotion()) { - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_FALSE); - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_FALSE); + SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, false); + SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, false); } - has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) == SDL_TRUE; - has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) == SDL_TRUE; + has_accel = SDL_GamepadHasSensor(controller, SDL_SENSOR_ACCEL); + has_gyro = SDL_GamepadHasSensor(controller, SDL_SENSOR_GYRO); if (has_accel) { - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE); + if (!SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, true)) { + LOG_WARNING(Input, "Failed to enable accelerometer sensor: {}", SDL_GetError()); + } } if (has_gyro) { - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); + if (!SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, true)) { + LOG_WARNING(Input, "Failed to enable gyroscope sensor: {}", SDL_GetError()); + } } + + LOG_INFO(Input, "Controller motion capabilities: accel={} gyro={}", has_accel, has_gyro); } bool HasMotion() const { return has_gyro || has_accel; } - bool UpdateMotion(SDL_ControllerSensorEvent event) { + bool UpdateMotion(SDL_GamepadSensorEvent event) { constexpr float gravity_constant = 9.80665f; std::scoped_lock lock{mutex}; - const u64 time_difference = event.timestamp - last_motion_update; - last_motion_update = event.timestamp; + const u64 sensor_timestamp = event.sensor_timestamp != 0 ? event.sensor_timestamp + : event.timestamp; + + if (last_motion_update == 0) { + last_motion_update = sensor_timestamp; + return false; + } + if (sensor_timestamp < last_motion_update) { + return false; + } + + // SDL3 reports sensor timestamps in nanoseconds, while the input stack expects + // delta timestamps in microseconds. + const u64 time_difference = (sensor_timestamp - last_motion_update) / 1000; + last_motion_update = sensor_timestamp; switch (event.sensor) { case SDL_SENSOR_ACCEL: { motion.accel_x = -event.data[0] / gravity_constant; @@ -102,7 +171,7 @@ public: } motion_error_count = 0; - motion.delta_timestamp = time_difference * 1000; + motion.delta_timestamp = time_difference; return true; } @@ -136,26 +205,41 @@ public: f32 high_amplitude = vibration.high_amplitude * high_frequency_scale; if (sdl_controller) { - return SDL_GameControllerRumble(sdl_controller.get(), static_cast(low_amplitude), - static_cast(high_amplitude), - rumble_max_duration_ms) != -1; + return SDL_RumbleGamepad(sdl_controller.get(), static_cast(low_amplitude), + static_cast(high_amplitude), rumble_max_duration_ms); } else if (sdl_joystick) { - return SDL_JoystickRumble(sdl_joystick.get(), static_cast(low_amplitude), + return SDL_RumbleJoystick(sdl_joystick.get(), static_cast(low_amplitude), static_cast(high_amplitude), - rumble_max_duration_ms) != -1; + rumble_max_duration_ms); } return false; } bool HasHDRumble() const { + constexpr Uint16 valve_vendor_id = 0x28DE; + const auto is_known_hd_type = [](SDL_GamepadType type) { + return type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO || + type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT || + type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT || + type == SDL_GAMEPAD_TYPE_PS5; + }; + + // Valve hardware doesn't have any enums in SDL, so we have to support it manually. + // Since they have HD rumble, we can assume that all their hardware supports it, even if we can't detect the exact type. if (sdl_controller) { - const auto type = SDL_GameControllerGetType(sdl_controller.get()); - return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) || - (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) || - (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) || - (type == SDL_CONTROLLER_TYPE_PS5); + if (is_known_hd_type(SDL_GetGamepadType(sdl_controller.get())) || + SDL_GetGamepadVendor(sdl_controller.get()) == valve_vendor_id) { + return true; + } } + + if (sdl_joystick) { + if (SDL_GetJoystickVendor(sdl_joystick.get()) == valve_vendor_id) { + return true; + } + } + return false; } @@ -201,11 +285,11 @@ public: return sdl_joystick.get(); } - SDL_GameController* GetSDLGameController() const { + SDL_Gamepad* GetSDLGameController() const { return sdl_controller.get(); } - void SetSDLJoystick(SDL_Joystick* joystick, SDL_GameController* controller) { + void SetSDLJoystick(SDL_Joystick* joystick, SDL_Gamepad* controller) { sdl_joystick.reset(joystick); sdl_controller.reset(controller); } @@ -232,20 +316,36 @@ public: return false; } - Common::Input::BatteryLevel GetBatteryLevel(SDL_JoystickPowerLevel battery_level) { - switch (battery_level) { - case SDL_JOYSTICK_POWER_EMPTY: - return Common::Input::BatteryLevel::Empty; - case SDL_JOYSTICK_POWER_LOW: - return Common::Input::BatteryLevel::Low; - case SDL_JOYSTICK_POWER_MEDIUM: - return Common::Input::BatteryLevel::Medium; - case SDL_JOYSTICK_POWER_FULL: - case SDL_JOYSTICK_POWER_MAX: - return Common::Input::BatteryLevel::Full; - case SDL_JOYSTICK_POWER_WIRED: + Common::Input::BatteryLevel GetBatteryLevel(SDL_PowerState battery_level, int percent) { + if (battery_level == SDL_POWERSTATE_CHARGING) { return Common::Input::BatteryLevel::Charging; - case SDL_JOYSTICK_POWER_UNKNOWN: + } + + if (percent >= 0 && percent <= 100) { + if (percent <= 5) { + return Common::Input::BatteryLevel::Empty; + } + if (percent <= 20) { + return Common::Input::BatteryLevel::Critical; + } + if (percent <= 40) { + return Common::Input::BatteryLevel::Low; + } + if (percent <= 70) { + return Common::Input::BatteryLevel::Medium; + } + return Common::Input::BatteryLevel::Full; + } + + switch (battery_level) { + case SDL_POWERSTATE_ON_BATTERY: + return Common::Input::BatteryLevel::Medium; + case SDL_POWERSTATE_NO_BATTERY: + return Common::Input::BatteryLevel::None; + case SDL_POWERSTATE_CHARGED: + return Common::Input::BatteryLevel::Full; + case SDL_POWERSTATE_ERROR: + case SDL_POWERSTATE_UNKNOWN: default: return Common::Input::BatteryLevel::None; } @@ -253,28 +353,28 @@ public: std::string GetControllerName() const { if (sdl_controller) { - switch (SDL_GameControllerGetType(sdl_controller.get())) { - case SDL_CONTROLLER_TYPE_XBOX360: + switch (SDL_GetGamepadType(sdl_controller.get())) { + case SDL_GAMEPAD_TYPE_XBOX360: return "Xbox 360 Controller"; - case SDL_CONTROLLER_TYPE_XBOXONE: + case SDL_GAMEPAD_TYPE_XBOXONE: return "Xbox One Controller"; - case SDL_CONTROLLER_TYPE_PS3: + case SDL_GAMEPAD_TYPE_PS3: return "DualShock 3 Controller"; - case SDL_CONTROLLER_TYPE_PS4: + case SDL_GAMEPAD_TYPE_PS4: return "DualShock 4 Controller"; - case SDL_CONTROLLER_TYPE_PS5: + case SDL_GAMEPAD_TYPE_PS5: return "DualSense Controller"; default: break; } - const auto name = SDL_GameControllerName(sdl_controller.get()); + const auto name = SDL_GetGamepadName(sdl_controller.get()); if (name) { return name; } } if (sdl_joystick) { - const auto name = SDL_JoystickName(sdl_joystick.get()); + const auto name = SDL_GetJoystickName(sdl_joystick.get()); if (name) { return name; } @@ -286,8 +386,8 @@ public: private: Common::UUID guid; int port; - std::unique_ptr sdl_joystick; - std::unique_ptr sdl_controller; + std::unique_ptr sdl_joystick; + std::unique_ptr sdl_controller; mutable std::mutex mutex; u64 last_motion_update{}; @@ -323,7 +423,10 @@ std::shared_ptr SDLDriver::GetSDLJoystickByGUID(const std::string& } std::shared_ptr SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { - auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); + auto sdl_joystick = SDL_GetJoystickFromID(sdl_id); + if (sdl_joystick == nullptr) { + return nullptr; + } const auto guid = GetGUID(sdl_joystick); std::scoped_lock lock{joystick_map_mutex}; @@ -345,34 +448,70 @@ std::shared_ptr SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl return *vec_it; } -void SDLDriver::InitJoystick(int joystick_index) { - SDL_Joystick* sdl_joystick = SDL_JoystickOpen(joystick_index); - SDL_GameController* sdl_gamecontroller = nullptr; +std::shared_ptr SDLDriver::GetSDLJoystickByGamepadID(SDL_JoystickID sdl_id) { + auto* const sdl_gamepad = SDL_GetGamepadFromID(sdl_id); + if (sdl_gamepad == nullptr) { + return nullptr; + } - if (SDL_IsGameController(joystick_index)) { - sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); + auto* const sdl_joystick = SDL_GetGamepadJoystick(sdl_gamepad); + if (sdl_joystick == nullptr) { + return nullptr; + } + + const auto guid = GetGUID(sdl_joystick); + + std::scoped_lock lock{joystick_map_mutex}; + const auto map_it = joystick_map.find(guid); + if (map_it == joystick_map.end()) { + return nullptr; + } + + const auto vec_it = std::find_if(map_it->second.begin(), map_it->second.end(), + [sdl_joystick, sdl_gamepad](const auto& joystick) { + return joystick->GetSDLJoystick() == sdl_joystick || + joystick->GetSDLGameController() == sdl_gamepad; + }); + + if (vec_it == map_it->second.end()) { + return nullptr; + } + + return *vec_it; +} + +void SDLDriver::InitJoystick(SDL_JoystickID joystick_id) { + SDL_Joystick* sdl_joystick = SDL_OpenJoystick(joystick_id); + SDL_Gamepad* sdl_gamecontroller = nullptr; + int battery_percent = -1; + SDL_PowerState battery_state = SDL_POWERSTATE_UNKNOWN; + + if (SDL_IsGamepad(joystick_id)) { + sdl_gamecontroller = SDL_OpenGamepad(joystick_id); } if (!sdl_joystick) { - LOG_ERROR(Input, "Failed to open joystick {}", joystick_index); + LOG_ERROR(Input, "Failed to open joystick {}", joystick_id); return; } + battery_state = SDL_GetJoystickPowerInfo(sdl_joystick, &battery_percent); + const auto guid = GetGUID(sdl_joystick); if (Settings::values.enable_joycon_driver) { if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && (guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) { - LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); - SDL_JoystickClose(sdl_joystick); + LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_id); + SDL_CloseJoystick(sdl_joystick); return; } } if (Settings::values.enable_procon_driver) { if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && guid.uuid[8] == 0x09) { - LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); - SDL_JoystickClose(sdl_joystick); + LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_id); + SDL_CloseJoystick(sdl_joystick); return; } } @@ -382,6 +521,8 @@ void SDLDriver::InitJoystick(int joystick_index) { auto joystick = std::make_shared(guid, 0, sdl_joystick, sdl_gamecontroller); PreSetController(joystick->GetPadIdentifier()); joystick->EnableMotion(); + SetBattery(joystick->GetPadIdentifier(), + joystick->GetBatteryLevel(battery_state, battery_percent)); joystick_map[guid].emplace_back(std::move(joystick)); return; } @@ -394,6 +535,8 @@ void SDLDriver::InitJoystick(int joystick_index) { if (joystick_it != joystick_guid_list.end()) { (*joystick_it)->SetSDLJoystick(sdl_joystick, sdl_gamecontroller); (*joystick_it)->EnableMotion(); + SetBattery((*joystick_it)->GetPadIdentifier(), + (*joystick_it)->GetBatteryLevel(battery_state, battery_percent)); return; } @@ -401,6 +544,8 @@ void SDLDriver::InitJoystick(int joystick_index) { auto joystick = std::make_shared(guid, port, sdl_joystick, sdl_gamecontroller); PreSetController(joystick->GetPadIdentifier()); joystick->EnableMotion(); + SetBattery(joystick->GetPadIdentifier(), + joystick->GetBatteryLevel(battery_state, battery_percent)); joystick_guid_list.emplace_back(std::move(joystick)); } @@ -428,55 +573,60 @@ void SDLDriver::PumpEvents() const { void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { switch (event.type) { - case SDL_JOYBUTTONUP: { + case SDL_EVENT_JOYSTICK_BUTTON_UP: { if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetButton(identifier, event.jbutton.button, false); } break; } - case SDL_JOYBUTTONDOWN: { + case SDL_EVENT_JOYSTICK_BUTTON_DOWN: { if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetButton(identifier, event.jbutton.button, true); } break; } - case SDL_JOYHATMOTION: { + case SDL_EVENT_JOYSTICK_HAT_MOTION: { if (const auto joystick = GetSDLJoystickBySDLID(event.jhat.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetHatButton(identifier, event.jhat.hat, event.jhat.value); } break; } - case SDL_JOYAXISMOTION: { + case SDL_EVENT_JOYSTICK_AXIS_MOTION: { if (const auto joystick = GetSDLJoystickBySDLID(event.jaxis.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetAxis(identifier, event.jaxis.axis, event.jaxis.value / 32767.0f); } break; } - case SDL_CONTROLLERSENSORUPDATE: { - if (auto joystick = GetSDLJoystickBySDLID(event.csensor.which)) { - if (joystick->UpdateMotion(event.csensor)) { + case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: { + auto joystick = GetSDLJoystickByGamepadID(event.gsensor.which); + if (!joystick) { + joystick = GetSDLJoystickBySDLID(event.gsensor.which); + } + if (joystick) { + if (joystick->UpdateMotion(event.gsensor)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetMotion(identifier, 0, joystick->GetMotion()); } } break; } - case SDL_JOYBATTERYUPDATED: { + case SDL_EVENT_JOYSTICK_BATTERY_UPDATED: { if (auto joystick = GetSDLJoystickBySDLID(event.jbattery.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); - SetBattery(identifier, joystick->GetBatteryLevel(event.jbattery.level)); + SetBattery(identifier, + joystick->GetBatteryLevel(event.jbattery.state, event.jbattery.percent)); } break; } - case SDL_JOYDEVICEREMOVED: + case SDL_EVENT_JOYSTICK_REMOVED: LOG_DEBUG(Input, "Controller removed with Instance_ID {}", event.jdevice.which); - CloseJoystick(SDL_JoystickFromInstanceID(event.jdevice.which)); + CloseJoystick(SDL_GetJoystickFromID(event.jdevice.which)); break; - case SDL_JOYDEVICEADDED: + case SDL_EVENT_JOYSTICK_ADDED: LOG_DEBUG(Input, "Controller connected with device index {}", event.jdevice.which); InitJoystick(event.jdevice.which); break; @@ -496,12 +646,13 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en // Disable raw input. When enabled this setting causes SDL to die when a web applet opens SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, Settings::values.enable_raw_input ? "1" : "0"); - // Prevent SDL from adding undesired axis - SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); + // SDL3 defaults Steam Controller Bluetooth HIDAPI support to off, which can disable gyro. + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAM, "1"); + SDL_SetHint(SDL_HINT_GAMECONTROLLER_SENSOR_FUSION, "1"); + SDL_SetHint(SDL_HINT_AUTO_UPDATE_SENSORS, "1"); // Enable HIDAPI rumble. This prevents SDL from disabling motion on PS4 and PS5 controllers - SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); - SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); // Disable hidapi drivers for joycon controllers when the custom joycon driver is enabled @@ -523,16 +674,13 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en } SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED, "1"); - // Share the same button mapping with non-Nintendo controllers - SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0"); - // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native // driver on Linux. SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0"); // If the frontend is going to manage the event loop, then we don't start one here - start_thread = SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == 0; - if (start_thread && SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) { + start_thread = SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) == 0; + if (start_thread && !SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) { LOG_CRITICAL(Input, "SDL_Init failed with: {}", SDL_GetError()); return; } @@ -552,19 +700,24 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en } // Because the events for joystick connection happens before we have our event watcher added, we // can just open all the joysticks right here - for (int i = 0; i < SDL_NumJoysticks(); ++i) { - InitJoystick(i); + int joystick_count = 0; + SDL_JoystickID* joysticks = SDL_GetJoysticks(&joystick_count); + if (joysticks != nullptr) { + for (int i = 0; i < joystick_count; ++i) { + InitJoystick(joysticks[i]); + } + SDL_free(joysticks); } } SDLDriver::~SDLDriver() { CloseJoysticks(); - SDL_DelEventWatch(&SDLEventWatcher, this); + SDL_RemoveEventWatch(&SDLEventWatcher, this); initialized = false; if (start_thread) { vibration_thread.join(); - SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); + SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD); } } @@ -758,17 +911,17 @@ Common::ParamPackage SDLDriver::BuildMotionParam(int port, const Common::UUID& g } Common::ParamPackage SDLDriver::BuildParamPackageForBinding( - int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const { - switch (binding.bindType) { - case SDL_CONTROLLER_BINDTYPE_NONE: + int port, const Common::UUID& guid, const SDL_GamepadBinding& binding) const { + switch (binding.input_type) { + case SDL_GAMEPAD_BINDTYPE_NONE: break; - case SDL_CONTROLLER_BINDTYPE_AXIS: - return BuildAnalogParamPackageForButton(port, guid, binding.value.axis); - case SDL_CONTROLLER_BINDTYPE_BUTTON: - return BuildButtonParamPackageForButton(port, guid, binding.value.button); - case SDL_CONTROLLER_BINDTYPE_HAT: - return BuildHatParamPackageForButton(port, guid, binding.value.hat.hat, - static_cast(binding.value.hat.hat_mask)); + case SDL_GAMEPAD_BINDTYPE_AXIS: + return BuildAnalogParamPackageForButton(port, guid, binding.input.axis.axis); + case SDL_GAMEPAD_BINDTYPE_BUTTON: + return BuildButtonParamPackageForButton(port, guid, binding.input.button); + case SDL_GAMEPAD_BINDTYPE_HAT: + return BuildHatParamPackageForButton(port, guid, binding.input.hat.hat, + static_cast(binding.input.hat.hat_mask)); } return {}; } @@ -808,8 +961,8 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p // Add the missing bindings for ZL/ZR static constexpr ZButtonBindings switch_to_sdl_axis{{ - {Settings::NativeButton::ZL, SDL_CONTROLLER_AXIS_TRIGGERLEFT}, - {Settings::NativeButton::ZR, SDL_CONTROLLER_AXIS_TRIGGERRIGHT}, + {Settings::NativeButton::ZL, SDL_GAMEPAD_AXIS_LEFT_TRIGGER}, + {Settings::NativeButton::ZR, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER}, }}; // Parameters contain two joysticks return dual @@ -828,41 +981,41 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p ButtonBindings SDLDriver::GetDefaultButtonBinding( const std::shared_ptr& joystick) const { // Default SL/SR mapping for other controllers - auto sll_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; - auto srl_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; - auto slr_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; - auto srr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; + auto sll_button = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER; + auto srl_button = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER; + auto slr_button = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER; + auto srr_button = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER; if (joystick->IsJoyconLeft()) { - sll_button = SDL_CONTROLLER_BUTTON_PADDLE2; - srl_button = SDL_CONTROLLER_BUTTON_PADDLE4; + sll_button = SDL_GAMEPAD_BUTTON_LEFT_PADDLE1; + srl_button = SDL_GAMEPAD_BUTTON_LEFT_PADDLE2; } if (joystick->IsJoyconRight()) { - slr_button = SDL_CONTROLLER_BUTTON_PADDLE3; - srr_button = SDL_CONTROLLER_BUTTON_PADDLE1; + slr_button = SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2; + srr_button = SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1; } return { - std::pair{Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_B}, - {Settings::NativeButton::B, SDL_CONTROLLER_BUTTON_A}, - {Settings::NativeButton::X, SDL_CONTROLLER_BUTTON_Y}, - {Settings::NativeButton::Y, SDL_CONTROLLER_BUTTON_X}, - {Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK}, - {Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, - {Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, - {Settings::NativeButton::R, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, - {Settings::NativeButton::Plus, SDL_CONTROLLER_BUTTON_START}, - {Settings::NativeButton::Minus, SDL_CONTROLLER_BUTTON_BACK}, - {Settings::NativeButton::DLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT}, - {Settings::NativeButton::DUp, SDL_CONTROLLER_BUTTON_DPAD_UP}, - {Settings::NativeButton::DRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT}, - {Settings::NativeButton::DDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN}, + std::pair{Settings::NativeButton::A, SDL_GAMEPAD_BUTTON_EAST}, + {Settings::NativeButton::B, SDL_GAMEPAD_BUTTON_SOUTH}, + {Settings::NativeButton::X, SDL_GAMEPAD_BUTTON_NORTH}, + {Settings::NativeButton::Y, SDL_GAMEPAD_BUTTON_WEST}, + {Settings::NativeButton::LStick, SDL_GAMEPAD_BUTTON_LEFT_STICK}, + {Settings::NativeButton::RStick, SDL_GAMEPAD_BUTTON_RIGHT_STICK}, + {Settings::NativeButton::L, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER}, + {Settings::NativeButton::R, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER}, + {Settings::NativeButton::Plus, SDL_GAMEPAD_BUTTON_START}, + {Settings::NativeButton::Minus, SDL_GAMEPAD_BUTTON_BACK}, + {Settings::NativeButton::DLeft, SDL_GAMEPAD_BUTTON_DPAD_LEFT}, + {Settings::NativeButton::DUp, SDL_GAMEPAD_BUTTON_DPAD_UP}, + {Settings::NativeButton::DRight, SDL_GAMEPAD_BUTTON_DPAD_RIGHT}, + {Settings::NativeButton::DDown, SDL_GAMEPAD_BUTTON_DPAD_DOWN}, {Settings::NativeButton::SLLeft, sll_button}, {Settings::NativeButton::SRLeft, srl_button}, {Settings::NativeButton::SLRight, slr_button}, {Settings::NativeButton::SRRight, srr_button}, - {Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE}, - {Settings::NativeButton::Screenshot, SDL_CONTROLLER_BUTTON_MISC1}, + {Settings::NativeButton::Home, SDL_GAMEPAD_BUTTON_GUIDE}, + {Settings::NativeButton::Screenshot, SDL_GAMEPAD_BUTTON_MISC1}, }; } @@ -872,15 +1025,16 @@ ButtonMapping SDLDriver::GetSingleControllerMapping( ButtonMapping mapping; mapping.reserve(switch_to_sdl_button.size() + switch_to_sdl_axis.size()); auto* controller = joystick->GetSDLGameController(); + const auto bindings = GetBindings(controller); for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { - const auto& binding = SDL_GameControllerGetBindForButton(controller, sdl_button); + const auto binding = GetBindingForButton(bindings, sdl_button); mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); } for (const auto& [switch_button, sdl_axis] : switch_to_sdl_axis) { - const auto& binding = SDL_GameControllerGetBindForAxis(controller, sdl_axis); + const auto binding = GetBindingForAxis(bindings, sdl_axis); mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); @@ -897,29 +1051,31 @@ ButtonMapping SDLDriver::GetDualControllerMapping(const std::shared_ptrGetSDLGameController(); auto* controller2 = joystick2->GetSDLGameController(); + const auto bindings = GetBindings(controller); + const auto bindings2 = GetBindings(controller2); for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { if (IsButtonOnLeftSide(switch_button)) { - const auto& binding = SDL_GameControllerGetBindForButton(controller2, sdl_button); + const auto binding = GetBindingForButton(bindings2, sdl_button); mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick2->GetPort(), joystick2->GetGUID(), binding)); continue; } - const auto& binding = SDL_GameControllerGetBindForButton(controller, sdl_button); + const auto binding = GetBindingForButton(bindings, sdl_button); mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); } for (const auto& [switch_button, sdl_axis] : switch_to_sdl_axis) { if (IsButtonOnLeftSide(switch_button)) { - const auto& binding = SDL_GameControllerGetBindForAxis(controller2, sdl_axis); + const auto binding = GetBindingForAxis(bindings2, sdl_axis); mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick2->GetPort(), joystick2->GetGUID(), binding)); continue; } - const auto& binding = SDL_GameControllerGetBindForAxis(controller, sdl_axis); + const auto binding = GetBindingForAxis(bindings, sdl_axis); mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); @@ -957,46 +1113,43 @@ AnalogMapping SDLDriver::GetAnalogMappingForDevice(const Common::ParamPackage& p } AnalogMapping mapping = {}; - const auto& binding_left_x = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); - const auto& binding_left_y = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); + const auto bindings = GetBindings(controller); + const auto binding_left_x = GetBindingForAxis(bindings, SDL_GAMEPAD_AXIS_LEFTX); + const auto binding_left_y = GetBindingForAxis(bindings, SDL_GAMEPAD_AXIS_LEFTY); if (params.Has("guid2")) { const auto identifier = joystick2->GetPadIdentifier(); PreSetController(identifier); - PreSetAxis(identifier, binding_left_x.value.axis); - PreSetAxis(identifier, binding_left_y.value.axis); - const auto left_offset_x = -GetAxis(identifier, binding_left_x.value.axis); - const auto left_offset_y = GetAxis(identifier, binding_left_y.value.axis); + PreSetAxis(identifier, binding_left_x.input.axis.axis); + PreSetAxis(identifier, binding_left_y.input.axis.axis); + const auto left_offset_x = -GetAxis(identifier, binding_left_x.input.axis.axis); + const auto left_offset_y = GetAxis(identifier, binding_left_y.input.axis.axis); mapping.insert_or_assign(Settings::NativeAnalog::LStick, - BuildParamPackageForAnalog(identifier, binding_left_x.value.axis, - binding_left_y.value.axis, + BuildParamPackageForAnalog(identifier, binding_left_x.input.axis.axis, + binding_left_y.input.axis.axis, left_offset_x, left_offset_y)); } else { const auto identifier = joystick->GetPadIdentifier(); PreSetController(identifier); - PreSetAxis(identifier, binding_left_x.value.axis); - PreSetAxis(identifier, binding_left_y.value.axis); - const auto left_offset_x = -GetAxis(identifier, binding_left_x.value.axis); - const auto left_offset_y = GetAxis(identifier, binding_left_y.value.axis); + PreSetAxis(identifier, binding_left_x.input.axis.axis); + PreSetAxis(identifier, binding_left_y.input.axis.axis); + const auto left_offset_x = -GetAxis(identifier, binding_left_x.input.axis.axis); + const auto left_offset_y = GetAxis(identifier, binding_left_y.input.axis.axis); mapping.insert_or_assign(Settings::NativeAnalog::LStick, - BuildParamPackageForAnalog(identifier, binding_left_x.value.axis, - binding_left_y.value.axis, + BuildParamPackageForAnalog(identifier, binding_left_x.input.axis.axis, + binding_left_y.input.axis.axis, left_offset_x, left_offset_y)); } - const auto& binding_right_x = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); - const auto& binding_right_y = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); + const auto binding_right_x = GetBindingForAxis(bindings, SDL_GAMEPAD_AXIS_RIGHTX); + const auto binding_right_y = GetBindingForAxis(bindings, SDL_GAMEPAD_AXIS_RIGHTY); const auto identifier = joystick->GetPadIdentifier(); PreSetController(identifier); - PreSetAxis(identifier, binding_right_x.value.axis); - PreSetAxis(identifier, binding_right_y.value.axis); - const auto right_offset_x = -GetAxis(identifier, binding_right_x.value.axis); - const auto right_offset_y = GetAxis(identifier, binding_right_y.value.axis); + PreSetAxis(identifier, binding_right_x.input.axis.axis); + PreSetAxis(identifier, binding_right_y.input.axis.axis); + const auto right_offset_x = -GetAxis(identifier, binding_right_x.input.axis.axis); + const auto right_offset_y = GetAxis(identifier, binding_right_y.input.axis.axis); mapping.insert_or_assign(Settings::NativeAnalog::RStick, - BuildParamPackageForAnalog(identifier, binding_right_x.value.axis, - binding_right_y.value.axis, right_offset_x, + BuildParamPackageForAnalog(identifier, binding_right_x.input.axis.axis, + binding_right_y.input.axis.axis, right_offset_x, right_offset_y)); return mapping; } @@ -1102,19 +1255,16 @@ bool SDLDriver::IsStickInverted(const Common::ParamPackage& params) { const auto& axis_x = params.Get("axis_x", 0); const auto& axis_y = params.Get("axis_y", 0); - const auto& binding_left_x = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); - const auto& binding_right_x = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); - const auto& binding_left_y = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); - const auto& binding_right_y = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); + const auto bindings = GetBindings(controller); + const auto binding_left_x = GetBindingForAxis(bindings, SDL_GAMEPAD_AXIS_LEFTX); + const auto binding_right_x = GetBindingForAxis(bindings, SDL_GAMEPAD_AXIS_RIGHTX); + const auto binding_left_y = GetBindingForAxis(bindings, SDL_GAMEPAD_AXIS_LEFTY); + const auto binding_right_y = GetBindingForAxis(bindings, SDL_GAMEPAD_AXIS_RIGHTY); - if (axis_x != binding_left_y.value.axis && axis_x != binding_right_y.value.axis) { + if (axis_x != binding_left_y.input.axis.axis && axis_x != binding_right_y.input.axis.axis) { return false; } - if (axis_y != binding_left_x.value.axis && axis_y != binding_right_x.value.axis) { + if (axis_y != binding_left_x.input.axis.axis && axis_y != binding_right_x.input.axis.axis) { return false; } return true; diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index 1677ab8289..bf4a45e83d 100644 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h @@ -11,25 +11,22 @@ #include #include -#include +#include #include "common/common_types.h" #include "common/threadsafe_queue.h" #include "input_common/input_engine.h" union SDL_Event; -using SDL_GameController = struct _SDL_GameController; -using SDL_Joystick = struct _SDL_Joystick; -using SDL_JoystickID = s32; namespace InputCommon { class SDLJoystick; using ButtonBindings = - std::array, 20>; + std::array, 20>; using ZButtonBindings = - std::array, 2>; + std::array, 2>; class SDLDriver : public InputEngine { public: @@ -46,6 +43,7 @@ public: /// Get the nth joystick with the corresponding GUID std::shared_ptr GetSDLJoystickBySDLID(SDL_JoystickID sdl_id); + std::shared_ptr GetSDLJoystickByGamepadID(SDL_JoystickID sdl_id); /** * Check how many identical joysticks (by guid) were connected before the one with sdl_id and so @@ -72,7 +70,7 @@ public: bool IsVibrationEnabled(const PadIdentifier& identifier) override; private: - void InitJoystick(int joystick_index); + void InitJoystick(SDL_JoystickID joystick_id); void CloseJoystick(SDL_Joystick* sdl_joystick); /// Needs to be called before SDL_QuitSubSystem. @@ -92,7 +90,7 @@ private: Common::ParamPackage BuildMotionParam(int port, const Common::UUID& guid) const; Common::ParamPackage BuildParamPackageForBinding( - int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const; + int port, const Common::UUID& guid, const SDL_GamepadBinding& binding) const; Common::ParamPackage BuildParamPackageForAnalog(PadIdentifier identifier, int axis_x, int axis_y, float offset_x, diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h index 792f124e14..dd3bd4398c 100644 --- a/src/input_common/helpers/joycon_protocol/joycon_types.h +++ b/src/input_common/helpers/joycon_protocol/joycon_types.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -10,7 +13,7 @@ #include #include -#include +#include #include "common/bit_field.h" #include "common/common_funcs.h" diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index b04a70590a..5f0a8af3aa 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp @@ -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: 2017 Citra Emulator Project @@ -25,7 +25,7 @@ #ifdef ENABLE_LIBUSB #include "input_common/drivers/gc_adapter.h" #endif -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 #include "input_common/drivers/joycon.h" #include "input_common/drivers/sdl_driver.h" #endif @@ -90,7 +90,7 @@ struct InputSubsystem::Impl { #endif RegisterEngine("virtual_amiibo", virtual_amiibo); RegisterEngine("virtual_gamepad", virtual_gamepad); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 RegisterEngine("sdl", sdl); RegisterEngine("joycon", joycon); #endif @@ -124,7 +124,7 @@ struct InputSubsystem::Impl { #endif UnregisterEngine(virtual_amiibo); UnregisterEngine(virtual_gamepad); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 UnregisterEngine(sdl); UnregisterEngine(joycon); #endif @@ -154,7 +154,7 @@ struct InputSubsystem::Impl { #endif auto udp_devices = udp_client->GetInputDevices(); devices.insert(devices.end(), udp_devices.begin(), udp_devices.end()); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 auto joycon_devices = joycon->GetInputDevices(); devices.insert(devices.end(), joycon_devices.begin(), joycon_devices.end()); auto sdl_devices = sdl->GetInputDevices(); @@ -189,7 +189,7 @@ struct InputSubsystem::Impl { if (engine == udp_client->GetEngineName()) { return udp_client; } -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 if (engine == sdl->GetEngineName()) { return sdl; } @@ -280,7 +280,7 @@ struct InputSubsystem::Impl { if (engine == virtual_gamepad->GetEngineName()) { return true; } -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 if (engine == sdl->GetEngineName()) { return true; } @@ -301,7 +301,7 @@ struct InputSubsystem::Impl { gcadapter->BeginConfiguration(); #endif udp_client->BeginConfiguration(); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 sdl->BeginConfiguration(); joycon->BeginConfiguration(); #endif @@ -317,7 +317,7 @@ struct InputSubsystem::Impl { gcadapter->EndConfiguration(); #endif udp_client->EndConfiguration(); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 sdl->EndConfiguration(); joycon->EndConfiguration(); #endif @@ -325,7 +325,7 @@ struct InputSubsystem::Impl { void PumpEvents() const { update_engine->PumpEvents(); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 sdl->PumpEvents(); #endif } @@ -350,7 +350,7 @@ struct InputSubsystem::Impl { std::shared_ptr gcadapter; #endif -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 std::shared_ptr sdl; std::shared_ptr joycon; #endif diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index ff0312660b..7468c06c06 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -466,6 +466,6 @@ if (NOT MSVC AND (APPLE OR NOT YUZU_STATIC_BUILD)) endif() # Remember that the linker is incredibly stupid. -target_link_libraries(yuzu PRIVATE OpenSSL::SSL OpenSSL::Crypto SDL2::SDL2) +target_link_libraries(yuzu PRIVATE OpenSSL::SSL OpenSSL::Crypto SDL3::SDL3) create_target_directory_groups(yuzu) diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index 7549325567..2bb83fa189 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -153,7 +153,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "video_core/renderer_base.h" #include "video_core/shader_notify.h" -#include +#include #include diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt index 35df53f381..09a9bd6da1 100644 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt @@ -17,20 +17,20 @@ endfunction() if (ENABLE_OPENGL) list(APPEND OPENGL_SOURCES - emu_window/emu_window_sdl2_gl.cpp - emu_window/emu_window_sdl2_gl.h + emu_window/emu_window_sdl3_gl.cpp + emu_window/emu_window_sdl3_gl.h ) else() set(OPENGL_SOURCES "") endif() add_executable(yuzu-cmd - emu_window/emu_window_sdl2.cpp - emu_window/emu_window_sdl2.h - emu_window/emu_window_sdl2_null.cpp - emu_window/emu_window_sdl2_null.h - emu_window/emu_window_sdl2_vk.cpp - emu_window/emu_window_sdl2_vk.h + emu_window/emu_window_sdl3.cpp + emu_window/emu_window_sdl3.h + emu_window/emu_window_sdl3_null.cpp + emu_window/emu_window_sdl3_null.h + emu_window/emu_window_sdl3_vk.cpp + emu_window/emu_window_sdl3_vk.h sdl_config.cpp sdl_config.h yuzu.cpp @@ -50,7 +50,7 @@ target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) create_resource("../../dist/eden.bmp" "yuzu_cmd/yuzu_icon.h" "yuzu_icon") target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR}) -target_link_libraries(yuzu-cmd PRIVATE SDL2::SDL2) +target_link_libraries(yuzu-cmd PRIVATE SDL3::SDL3) if(UNIX AND NOT APPLE) install(TARGETS yuzu-cmd) diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp deleted file mode 100644 index c54e5b4fda..0000000000 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include - -#include - -#include "common/logging.h" -#include "common/scm_rev.h" -#include "video_core/renderer_vulkan/renderer_vulkan.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" - -#include -#include - -EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, - Core::System& system_, bool fullscreen) - : EmuWindow_SDL2{input_subsystem_, system_} { - const std::string window_title = fmt::format("Eden {} | {}-{} (Vulkan)", - Common::g_build_name, - Common::g_scm_branch, - Common::g_scm_desc); - render_window = - SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); - - SDL_SysWMinfo wm; - SDL_VERSION(&wm.version); - if (SDL_GetWindowWMInfo(render_window, &wm) == SDL_FALSE) { - LOG_CRITICAL(Frontend, "Failed to get information from the window manager: {}", - SDL_GetError()); - std::exit(EXIT_FAILURE); - } - - SetWindowIcon(); - - if (fullscreen) { - Fullscreen(); - ShowCursor(false); - } - - switch (wm.subsystem) { -#ifdef SDL_VIDEO_DRIVER_WINDOWS - case SDL_SYSWM_TYPE::SDL_SYSWM_WINDOWS: - window_info.type = Core::Frontend::WindowSystemType::Windows; - window_info.render_surface = reinterpret_cast(wm.info.win.window); - break; -#endif -#ifdef SDL_VIDEO_DRIVER_X11 - case SDL_SYSWM_TYPE::SDL_SYSWM_X11: - window_info.type = Core::Frontend::WindowSystemType::X11; - window_info.display_connection = wm.info.x11.display; - window_info.render_surface = reinterpret_cast(wm.info.x11.window); - break; -#endif -#ifdef SDL_VIDEO_DRIVER_WAYLAND - case SDL_SYSWM_TYPE::SDL_SYSWM_WAYLAND: - window_info.type = Core::Frontend::WindowSystemType::Wayland; - window_info.display_connection = wm.info.wl.display; - window_info.render_surface = wm.info.wl.surface; - break; -#endif -#ifdef SDL_VIDEO_DRIVER_COCOA - case SDL_SYSWM_TYPE::SDL_SYSWM_COCOA: - window_info.type = Core::Frontend::WindowSystemType::Cocoa; - window_info.render_surface = SDL_Metal_CreateView(render_window); - break; -#endif -#ifdef SDL_VIDEO_DRIVER_ANDROID - case SDL_SYSWM_TYPE::SDL_SYSWM_ANDROID: - window_info.type = Core::Frontend::WindowSystemType::Android; - window_info.render_surface = reinterpret_cast(wm.info.android.window); - break; -#endif - default: - LOG_CRITICAL(Frontend, "Window manager subsystem {} not implemented", wm.subsystem); - std::exit(EXIT_FAILURE); - break; - } - - OnResize(); - OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); - SDL_PumpEvents(); - LOG_INFO(Frontend, "Eden Version: {} | {}-{} (Vulkan)", Common::g_build_name, - Common::g_scm_branch, Common::g_scm_desc); -} - -EmuWindow_SDL2_VK::~EmuWindow_SDL2_VK() = default; - -std::unique_ptr EmuWindow_SDL2_VK::CreateSharedContext() const { - return std::make_unique(); -} diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl3.cpp similarity index 68% rename from src/yuzu_cmd/emu_window/emu_window_sdl2.cpp rename to src/yuzu_cmd/emu_window/emu_window_sdl3.cpp index c00734216e..cd390d29f9 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl3.cpp @@ -1,9 +1,10 @@ // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include +#include #include "common/logging.h" #include "common/scm_rev.h" @@ -15,26 +16,25 @@ #include "input_common/drivers/mouse.h" #include "input_common/drivers/touch_screen.h" #include "input_common/main.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3.h" #include "yuzu_cmd/yuzu_icon.h" -EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_) +EmuWindow_SDL3::EmuWindow_SDL3(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_) : input_subsystem{input_subsystem_}, system{system_} { input_subsystem->Initialize(); - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) { - LOG_CRITICAL(Frontend, "Failed to initialize SDL2: {}, Exiting...", SDL_GetError()); + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) { + LOG_CRITICAL(Frontend, "Failed to initialize SDL3: {}, Exiting...", SDL_GetError()); exit(1); } - SDL_SetMainReady(); } -EmuWindow_SDL2::~EmuWindow_SDL2() { +EmuWindow_SDL3::~EmuWindow_SDL3() { system.HIDCore().UnloadInputDevices(); input_subsystem->Shutdown(); SDL_Quit(); } -InputCommon::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) const { +InputCommon::MouseButton EmuWindow_SDL3::SDLButtonToMouseButton(u32 button) const { switch (button) { case SDL_BUTTON_LEFT: return InputCommon::MouseButton::Left; @@ -52,7 +52,7 @@ InputCommon::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) cons } /// @brief Translates pixel position to float position -EmuWindow_SDL2::FloatPairNonHFA EmuWindow_SDL2::MouseToTouchPos(s32 touch_x, s32 touch_y) const { +EmuWindow_SDL3::FloatPairNonHFA EmuWindow_SDL3::MouseToTouchPos(s32 touch_x, s32 touch_y) const { int w = 0, h = 0; SDL_GetWindowSize(render_window, &w, &h); const float fx = float(touch_x) / w; @@ -64,9 +64,9 @@ EmuWindow_SDL2::FloatPairNonHFA EmuWindow_SDL2::MouseToTouchPos(s32 touch_x, s32 }; } -void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { +void EmuWindow_SDL3::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { const auto mouse_button = SDLButtonToMouseButton(button); - if (state == SDL_PRESSED) { + if (state != 0) { auto const [touch_x, touch_y, _] = MouseToTouchPos(x, y); input_subsystem->GetMouse()->PressButton(x, y, mouse_button); input_subsystem->GetMouse()->PressMouseButton(mouse_button); @@ -76,64 +76,70 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { } } -void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { +void EmuWindow_SDL3::OnMouseMotion(s32 x, s32 y) { auto const [touch_x, touch_y, _] = MouseToTouchPos(x, y); input_subsystem->GetMouse()->Move(x, y, 0, 0); input_subsystem->GetMouse()->MouseMove(touch_x, touch_y); input_subsystem->GetMouse()->TouchMove(touch_x, touch_y); } -void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) { +void EmuWindow_SDL3::OnFingerDown(float x, float y, std::size_t id) { input_subsystem->GetTouchScreen()->TouchPressed(x, y, id); } -void EmuWindow_SDL2::OnFingerMotion(float x, float y, std::size_t id) { +void EmuWindow_SDL3::OnFingerMotion(float x, float y, std::size_t id) { input_subsystem->GetTouchScreen()->TouchMoved(x, y, id); } -void EmuWindow_SDL2::OnFingerUp() { +void EmuWindow_SDL3::OnFingerUp() { input_subsystem->GetTouchScreen()->ReleaseAllTouch(); } -void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) { - if (state == SDL_PRESSED) { +void EmuWindow_SDL3::OnKeyEvent(int key, u8 state) { + if (state != 0) { input_subsystem->GetKeyboard()->PressKey(static_cast(key)); - } else if (state == SDL_RELEASED) { + } else { input_subsystem->GetKeyboard()->ReleaseKey(static_cast(key)); } } -bool EmuWindow_SDL2::IsOpen() const { +bool EmuWindow_SDL3::IsOpen() const { return is_open; } -bool EmuWindow_SDL2::IsShown() const { +bool EmuWindow_SDL3::IsShown() const { return is_shown; } -void EmuWindow_SDL2::OnResize() { +void EmuWindow_SDL3::OnResize() { int width, height; - SDL_GL_GetDrawableSize(render_window, &width, &height); + SDL_GetWindowSizeInPixels(render_window, &width, &height); UpdateCurrentFramebufferLayout(width, height); } -void EmuWindow_SDL2::ShowCursor(bool show_cursor) { - SDL_ShowCursor(show_cursor ? SDL_ENABLE : SDL_DISABLE); +void EmuWindow_SDL3::ShowCursor(bool show_cursor) { + if (show_cursor) { + SDL_ShowCursor(); + } else { + SDL_HideCursor(); + } } -void EmuWindow_SDL2::Fullscreen() { +void EmuWindow_SDL3::Fullscreen() { SDL_DisplayMode display_mode; switch (Settings::values.fullscreen_mode.GetValue()) { case Settings::FullscreenMode::Exclusive: - // Set window size to render size before entering fullscreen -- SDL2 does not resize window - // to display dimensions automatically in this mode. - if (SDL_GetDesktopDisplayMode(0, &display_mode) == 0) { + // Set window size to render size before entering fullscreen in exclusive mode. + if (const SDL_DisplayMode* display_mode_ptr = + SDL_GetDesktopDisplayMode(SDL_GetDisplayForWindow(render_window))) { + display_mode = *display_mode_ptr; SDL_SetWindowSize(render_window, display_mode.w, display_mode.h); + SDL_SetWindowFullscreenMode(render_window, &display_mode); } else { LOG_ERROR(Frontend, "SDL_GetDesktopDisplayMode failed: {}", SDL_GetError()); } - if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN) == 0) { + if (SDL_SetWindowFullscreen(render_window, true)) { return; } @@ -141,7 +147,8 @@ void EmuWindow_SDL2::Fullscreen() { LOG_INFO(Frontend, "Attempting to use borderless fullscreen..."); [[fallthrough]]; case Settings::FullscreenMode::Borderless: - if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) { + SDL_SetWindowFullscreenMode(render_window, nullptr); + if (SDL_SetWindowFullscreen(render_window, true)) { return; } @@ -156,7 +163,7 @@ void EmuWindow_SDL2::Fullscreen() { } } -void EmuWindow_SDL2::WaitEvent() { +void EmuWindow_SDL3::WaitEvent() { // Called on main thread SDL_Event event; @@ -174,52 +181,52 @@ void EmuWindow_SDL2::WaitEvent() { } switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_SIZE_CHANGED: - case SDL_WINDOWEVENT_RESIZED: - case SDL_WINDOWEVENT_MAXIMIZED: - case SDL_WINDOWEVENT_RESTORED: - OnResize(); - break; - case SDL_WINDOWEVENT_MINIMIZED: - case SDL_WINDOWEVENT_EXPOSED: - is_shown = event.window.event == SDL_WINDOWEVENT_EXPOSED; - OnResize(); - break; - case SDL_WINDOWEVENT_CLOSE: - is_open = false; - break; - } + case SDL_EVENT_WINDOW_RESIZED: + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + case SDL_EVENT_WINDOW_MAXIMIZED: + case SDL_EVENT_WINDOW_RESTORED: + OnResize(); break; - case SDL_KEYDOWN: - case SDL_KEYUP: - OnKeyEvent(static_cast(event.key.keysym.scancode), event.key.state); + case SDL_EVENT_WINDOW_MINIMIZED: + is_shown = false; + OnResize(); break; - case SDL_MOUSEMOTION: + case SDL_EVENT_WINDOW_EXPOSED: + is_shown = true; + OnResize(); + break; + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + is_open = false; + break; + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: + OnKeyEvent(static_cast(event.key.scancode), event.key.down ? 1 : 0); + break; + case SDL_EVENT_MOUSE_MOTION: // ignore if it came from touch if (event.button.which != SDL_TOUCH_MOUSEID) OnMouseMotion(event.motion.x, event.motion.y); break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: // ignore if it came from touch if (event.button.which != SDL_TOUCH_MOUSEID) { - OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y); + OnMouseButton(event.button.button, event.button.down ? 1 : 0, + static_cast(event.button.x), static_cast(event.button.y)); } break; - case SDL_FINGERDOWN: + case SDL_EVENT_FINGER_DOWN: OnFingerDown(event.tfinger.x, event.tfinger.y, - static_cast(event.tfinger.touchId)); + static_cast(event.tfinger.touchID)); break; - case SDL_FINGERMOTION: + case SDL_EVENT_FINGER_MOTION: OnFingerMotion(event.tfinger.x, event.tfinger.y, - static_cast(event.tfinger.touchId)); + static_cast(event.tfinger.touchID)); break; - case SDL_FINGERUP: + case SDL_EVENT_FINGER_UP: OnFingerUp(); break; - case SDL_QUIT: + case SDL_EVENT_QUIT: is_open = false; break; default: @@ -241,22 +248,22 @@ void EmuWindow_SDL2::WaitEvent() { } // Credits to Samantas5855 and others for this function. -void EmuWindow_SDL2::SetWindowIcon() { - SDL_RWops* const yuzu_icon_stream = SDL_RWFromConstMem((void*)yuzu_icon, yuzu_icon_size); +void EmuWindow_SDL3::SetWindowIcon() { + SDL_IOStream* const yuzu_icon_stream = SDL_IOFromConstMem((void*)yuzu_icon, yuzu_icon_size); if (yuzu_icon_stream == nullptr) { LOG_WARNING(Frontend, "Failed to create Eden icon stream."); return; } - SDL_Surface* const window_icon = SDL_LoadBMP_RW(yuzu_icon_stream, 1); + SDL_Surface* const window_icon = SDL_LoadBMP_IO(yuzu_icon_stream, true); if (window_icon == nullptr) { LOG_WARNING(Frontend, "Failed to read BMP from stream."); return; } // The icon is attached to the window pointer SDL_SetWindowIcon(render_window, window_icon); - SDL_FreeSurface(window_icon); + SDL_DestroySurface(window_icon); } -void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair minimal_size) { +void EmuWindow_SDL3::OnMinimalClientAreaChangeRequest(std::pair minimal_size) { SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl3.h similarity index 92% rename from src/yuzu_cmd/emu_window/emu_window_sdl2.h rename to src/yuzu_cmd/emu_window/emu_window_sdl3.h index 8aec1efda0..8e809a3f02 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl3.h @@ -1,5 +1,6 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -22,10 +23,10 @@ class InputSubsystem; enum class MouseButton; } // namespace InputCommon -class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { +class EmuWindow_SDL3 : public Core::Frontend::EmuWindow { public: - explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_); - ~EmuWindow_SDL2(); + explicit EmuWindow_SDL3(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_); + ~EmuWindow_SDL3(); /// Whether the window is still open, and a close request hasn't yet been sent bool IsOpen() const; @@ -85,7 +86,7 @@ protected: /// Is the window being shown? bool is_shown = true; - /// Internal SDL2 render window + /// Internal SDL3 render window SDL_Window* render_window{}; /// Keeps track of how often to update the title bar during gameplay diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl3_gl.cpp similarity index 79% rename from src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp rename to src/yuzu_cmd/emu_window/emu_window_sdl3_gl.cpp index 448c902131..e86858a232 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl3_gl.cpp @@ -9,7 +9,7 @@ #include #define SDL_MAIN_HANDLED -#include +#include #include #include @@ -20,7 +20,13 @@ #include "core/core.h" #include "input_common/main.h" #include "video_core/renderer_base.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3_gl.h" + +namespace { +void* SDLGLGetProcAddress(const char* proc_name) { + return reinterpret_cast(SDL_GL_GetProcAddress(proc_name)); +} +} // Anonymous namespace class SDLGLContext : public Core::Frontend::GraphicsContext { public: @@ -30,7 +36,7 @@ public: ~SDLGLContext() { DoneCurrent(); - SDL_GL_DeleteContext(context); + SDL_GL_DestroyContext(context); } void SwapBuffers() override { @@ -58,7 +64,7 @@ private: bool is_current = false; }; -bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { +bool EmuWindow_SDL3_GL::SupportsRequiredGLExtensions() { std::vector unsupported_ext{}; #ifdef HAS_OPENGL // Extensions required to support some texture formats. @@ -72,9 +78,9 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { return unsupported_ext.empty(); } -EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, +EmuWindow_SDL3_GL::EmuWindow_SDL3_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) - : EmuWindow_SDL2{input_subsystem_, system_} { + : EmuWindow_SDL3{input_subsystem_, system_} { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); @@ -92,14 +98,13 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste std::string window_title = fmt::format("{} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); render_window = - SDL_CreateWindow(window_title.c_str(), - SDL_WINDOWPOS_UNDEFINED, // x position - SDL_WINDOWPOS_UNDEFINED, // y position - Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, - SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_CreateWindow(window_title.c_str(), Layout::ScreenUndocked::Width, + Layout::ScreenUndocked::Height, + SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | + SDL_WINDOW_HIGH_PIXEL_DENSITY); if (render_window == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create SDL2 window! {}", SDL_GetError()); + LOG_CRITICAL(Frontend, "Failed to create SDL3 window! {}", SDL_GetError()); exit(1); } @@ -116,15 +121,15 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste core_context = CreateSharedContext(); if (window_context == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context: {}", SDL_GetError()); + LOG_CRITICAL(Frontend, "Failed to create SDL3 GL context: {}", SDL_GetError()); exit(1); } if (core_context == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create shared SDL2 GL context: {}", SDL_GetError()); + LOG_CRITICAL(Frontend, "Failed to create shared SDL3 GL context: {}", SDL_GetError()); exit(1); } - if (!gladLoadGLLoader(static_cast(SDL_GL_GetProcAddress))) { + if (!gladLoadGLLoader(static_cast(SDLGLGetProcAddress))) { LOG_CRITICAL(Frontend, "Failed to initialize GL functions! {}", SDL_GetError()); exit(1); } @@ -142,11 +147,11 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste Settings::LogSettings(); } -EmuWindow_SDL2_GL::~EmuWindow_SDL2_GL() { +EmuWindow_SDL3_GL::~EmuWindow_SDL3_GL() { core_context.reset(); - SDL_GL_DeleteContext(window_context); + SDL_GL_DestroyContext(window_context); } -std::unique_ptr EmuWindow_SDL2_GL::CreateSharedContext() const { +std::unique_ptr EmuWindow_SDL3_GL::CreateSharedContext() const { return std::make_unique(render_window); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h b/src/yuzu_cmd/emu_window/emu_window_sdl3_gl.h similarity index 70% rename from src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h rename to src/yuzu_cmd/emu_window/emu_window_sdl3_gl.h index 39346e7047..73a7d3d482 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl3_gl.h @@ -1,11 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include +#include #include "core/frontend/emu_window.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3.h" namespace Core { class System; @@ -15,11 +19,11 @@ namespace InputCommon { class InputSubsystem; } -class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 { +class EmuWindow_SDL3_GL final : public EmuWindow_SDL3 { public: - explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, + explicit EmuWindow_SDL3_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen); - ~EmuWindow_SDL2_GL(); + ~EmuWindow_SDL3_GL(); std::unique_ptr CreateSharedContext() const override; @@ -27,8 +31,6 @@ private: /// Whether the GPU and driver supports the OpenGL extension required bool SupportsRequiredGLExtensions(); - using SDL_GLContext = void*; - /// The OpenGL context associated with the window SDL_GLContext window_context; diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl3_null.cpp similarity index 67% rename from src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp rename to src/yuzu_cmd/emu_window/emu_window_sdl3_null.cpp index 4947080313..f5e4e19a30 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl3_null.cpp @@ -13,25 +13,25 @@ #include "common/logging.h" #include "common/scm_rev.h" #include "video_core/renderer_null/renderer_null.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2_null.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3_null.h" -#ifdef YUZU_USE_EXTERNAL_SDL2 +#ifdef YUZU_USE_EXTERNAL_SDL3 // Include this before SDL.h to prevent the external from including a dummy #define USING_GENERATED_CONFIG_H -#include +#include #endif -#include +#include -EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subsystem_, +EmuWindow_SDL3_Null::EmuWindow_SDL3_Null(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) - : EmuWindow_SDL2{input_subsystem_, system_} { + : EmuWindow_SDL3{input_subsystem_, system_} { const std::string window_title = fmt::format("Eden {} | {}-{} (Vulkan)", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); render_window = - SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_CreateWindow(window_title.c_str(), Layout::ScreenUndocked::Width, + Layout::ScreenUndocked::Height, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); SetWindowIcon(); @@ -47,8 +47,8 @@ EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subs Common::g_scm_branch, Common::g_scm_desc); } -EmuWindow_SDL2_Null::~EmuWindow_SDL2_Null() = default; +EmuWindow_SDL3_Null::~EmuWindow_SDL3_Null() = default; -std::unique_ptr EmuWindow_SDL2_Null::CreateSharedContext() const { +std::unique_ptr EmuWindow_SDL3_Null::CreateSharedContext() const { return std::make_unique(); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.h b/src/yuzu_cmd/emu_window/emu_window_sdl3_null.h similarity index 58% rename from src/yuzu_cmd/emu_window/emu_window_sdl2_null.h rename to src/yuzu_cmd/emu_window/emu_window_sdl3_null.h index 35aee286df..7c046e72b8 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl3_null.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -6,7 +9,7 @@ #include #include "core/frontend/emu_window.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3.h" namespace Core { class System; @@ -16,11 +19,11 @@ namespace InputCommon { class InputSubsystem; } -class EmuWindow_SDL2_Null final : public EmuWindow_SDL2 { +class EmuWindow_SDL3_Null final : public EmuWindow_SDL3 { public: - explicit EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subsystem_, + explicit EmuWindow_SDL3_Null(InputCommon::InputSubsystem* input_subsystem_, Core::System& system, bool fullscreen); - ~EmuWindow_SDL2_Null() override; + ~EmuWindow_SDL3_Null() override; std::unique_ptr CreateSharedContext() const override; }; diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl3_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl3_vk.cpp new file mode 100644 index 0000000000..9019cbbba0 --- /dev/null +++ b/src/yuzu_cmd/emu_window/emu_window_sdl3_vk.cpp @@ -0,0 +1,99 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include + +#include + +#include "common/logging.h" +#include "common/scm_rev.h" +#include "video_core/renderer_vulkan/renderer_vulkan.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3_vk.h" + +#include +#include + +EmuWindow_SDL3_VK::EmuWindow_SDL3_VK(InputCommon::InputSubsystem* input_subsystem_, + Core::System& system_, bool fullscreen) + : EmuWindow_SDL3{input_subsystem_, system_} { + const std::string window_title = fmt::format("Eden {} | {}-{} (Vulkan)", + Common::g_build_name, + Common::g_scm_branch, + Common::g_scm_desc); + render_window = + SDL_CreateWindow(window_title.c_str(), Layout::ScreenUndocked::Width, + Layout::ScreenUndocked::Height, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); + + const SDL_PropertiesID window_props = SDL_GetWindowProperties(render_window); + + SetWindowIcon(); + + if (fullscreen) { + Fullscreen(); + ShowCursor(false); + } + + if (void* hwnd = + SDL_GetPointerProperty(window_props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr)) { + window_info.type = Core::Frontend::WindowSystemType::Windows; + window_info.render_surface = hwnd; + } else if (void* wl_display = + SDL_GetPointerProperty(window_props, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, + nullptr); + wl_display != nullptr) { + void* wl_surface = + SDL_GetPointerProperty(window_props, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr); + if (wl_surface == nullptr) { + LOG_CRITICAL(Frontend, "Wayland surface is unavailable"); + std::exit(EXIT_FAILURE); + } + window_info.type = Core::Frontend::WindowSystemType::Wayland; + window_info.display_connection = wl_display; + window_info.render_surface = wl_surface; + } else if (void* x11_display = + SDL_GetPointerProperty(window_props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, + nullptr); + x11_display != nullptr) { + const auto x11_window = + SDL_GetNumberProperty(window_props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); + if (x11_window == 0) { + LOG_CRITICAL(Frontend, "X11 window handle is unavailable"); + std::exit(EXIT_FAILURE); + } + window_info.type = Core::Frontend::WindowSystemType::X11; + window_info.display_connection = x11_display; + window_info.render_surface = reinterpret_cast(static_cast(x11_window)); + } else if (SDL_GetPointerProperty(window_props, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, + nullptr) != nullptr) { + window_info.type = Core::Frontend::WindowSystemType::Cocoa; + window_info.render_surface = SDL_Metal_CreateView(render_window); + } else if (void* android_window = + SDL_GetPointerProperty(window_props, SDL_PROP_WINDOW_ANDROID_WINDOW_POINTER, + nullptr); + android_window != nullptr) { + window_info.type = Core::Frontend::WindowSystemType::Android; + window_info.render_surface = android_window; + } else { + LOG_CRITICAL(Frontend, "Unable to determine native window backend from SDL properties"); + std::exit(EXIT_FAILURE); + } + + OnResize(); + OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); + SDL_PumpEvents(); + LOG_INFO(Frontend, "Eden Version: {} | {}-{} (Vulkan)", Common::g_build_name, + Common::g_scm_branch, Common::g_scm_desc); +} + +EmuWindow_SDL3_VK::~EmuWindow_SDL3_VK() = default; + +std::unique_ptr EmuWindow_SDL3_VK::CreateSharedContext() const { + return std::make_unique(); +} diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h b/src/yuzu_cmd/emu_window/emu_window_sdl3_vk.h similarity index 59% rename from src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h rename to src/yuzu_cmd/emu_window/emu_window_sdl3_vk.h index 9467d164a4..5eb2626dd7 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl3_vk.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -6,7 +9,7 @@ #include #include "core/frontend/emu_window.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3.h" namespace Core { class System; @@ -16,11 +19,11 @@ namespace InputCommon { class InputSubsystem; } -class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 { +class EmuWindow_SDL3_VK final : public EmuWindow_SDL3 { public: - explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system, + explicit EmuWindow_SDL3_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system, bool fullscreen); - ~EmuWindow_SDL2_VK() override; + ~EmuWindow_SDL3_VK() override; std::unique_ptr CreateSharedContext() const override; }; diff --git a/src/yuzu_cmd/sdl_config.cpp b/src/yuzu_cmd/sdl_config.cpp index 136043dc9e..b06a5a698c 100644 --- a/src/yuzu_cmd/sdl_config.cpp +++ b/src/yuzu_cmd/sdl_config.cpp @@ -6,7 +6,7 @@ // SDL will break our main function in yuzu-cmd if we don't define this before adding SDL.h #define SDL_MAIN_HANDLED -#include +#include #include "common/logging.h" #include "input_common/main.h" diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 54cc832bf2..d20c126159 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -30,12 +30,12 @@ #include "network/network.h" #include "sdl_config.h" #include "video_core/renderer_base.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3.h" #ifdef HAS_OPENGL -#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3_gl.h" #endif -#include "yuzu_cmd/emu_window/emu_window_sdl2_null.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3_null.h" +#include "yuzu_cmd/emu_window/emu_window_sdl3_vk.h" #ifdef _WIN32 // windows.h needs to be included before shellapi.h @@ -349,20 +349,20 @@ int main(int argc, char** argv) { // Apply the command line arguments system.ApplySettings(); - std::unique_ptr emu_window; + std::unique_ptr emu_window; switch (Settings::values.renderer_backend.GetValue()) { #ifdef HAS_OPENGL case Settings::RendererBackend::OpenGL_GLSL: case Settings::RendererBackend::OpenGL_GLASM: case Settings::RendererBackend::OpenGL_SPIRV: - emu_window = std::make_unique(&input_subsystem, system, fullscreen); + emu_window = std::make_unique(&input_subsystem, system, fullscreen); break; #endif case Settings::RendererBackend::Vulkan: - emu_window = std::make_unique(&input_subsystem, system, fullscreen); + emu_window = std::make_unique(&input_subsystem, system, fullscreen); break; case Settings::RendererBackend::Null: - emu_window = std::make_unique(&input_subsystem, system, fullscreen); + emu_window = std::make_unique(&input_subsystem, system, fullscreen); break; default: LOG_CRITICAL(Frontend, "Invalid renderer backend"); From 5ab02276242f9ef2324f164390504db6169f68f4 Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 18 May 2026 21:44:29 +0200 Subject: [PATCH 50/58] [cmake] Fix reversed YUZU_USE_BUNDLED_SDL3 (#3980) oops Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3980 --- externals/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 72dafa4704..13de8f567d 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -136,7 +136,7 @@ if(ENABLE_CUBEB) endif() if (NOT ANDROID) - if (YUZU_USE_BUNDLED_SDL3) + if (NOT YUZU_USE_BUNDLED_SDL3) if (NOT WIN32) # Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers # Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095) From 74558545289ea47e77f1364728cdd2371c7429cb Mon Sep 17 00:00:00 2001 From: lizzie Date: Mon, 18 May 2026 23:28:01 +0200 Subject: [PATCH 51/58] [core/memory] remove duplicates from template when unsafe=T/F, remove increment, remove sad path for exception code on cache op (#3972) Ideally this should increase perf when doing write/read operations not by a lot, just enough for it not to suck so much as it does right now Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3972 Reviewed-by: MaranBr Reviewed-by: Maufeat --- src/core/memory.cpp | 320 ++++++++++++++++---------------------------- 1 file changed, 115 insertions(+), 205 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 3a9ea308a8..38e77e863f 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -58,9 +58,9 @@ struct Memory::Impl { #ifdef __ANDROID__ heap_tracker.emplace(system.DeviceMemory().buffer); - buffer = std::addressof(*heap_tracker); + host_buffer = std::addressof(*heap_tracker); #else - buffer = std::addressof(system.DeviceMemory().buffer); + host_buffer = std::addressof(system.DeviceMemory().buffer); #endif } @@ -75,8 +75,7 @@ struct Memory::Impl { Common::PageType::Memory); if (current_page_table->fastmem_arena) { - buffer->Map(GetInteger(base), GetInteger(target) - DramMemoryMap::Base, size, perms, - separate_heap); + host_buffer->Map(GetInteger(base), GetInteger(target) - DramMemoryMap::Base, size, perms, separate_heap); } } @@ -88,7 +87,7 @@ struct Memory::Impl { Common::PageType::Unmapped); if (current_page_table->fastmem_arena) { - buffer->Unmap(GetInteger(base), size, separate_heap); + host_buffer->Unmap(GetInteger(base), size, separate_heap); } } @@ -107,7 +106,7 @@ struct Memory::Impl { switch (page_type) { case Common::PageType::RasterizerCachedMemory: if (protect_bytes > 0) { - buffer->Protect(protect_begin, protect_bytes, perms); + host_buffer->Protect(protect_begin, protect_bytes, perms); protect_bytes = 0; } break; @@ -119,7 +118,7 @@ struct Memory::Impl { } if (protect_bytes > 0) { - buffer->Protect(protect_begin, protect_bytes, perms); + host_buffer->Protect(protect_begin, protect_bytes, perms); } } @@ -233,225 +232,138 @@ struct Memory::Impl { return string; } - bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped, - auto on_memory, auto on_rasterizer, auto increment) { - const auto& page_table = *current_page_table; + template + inline bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, F1&& on_unmapped, F2&& on_memory, F3&& on_rasterizer) { + std::size_t offset = 0; + if (!AddressSpaceContains(*current_page_table, addr, size)) { + on_unmapped(offset, size, addr); + return false; + } std::size_t remaining_size = size; std::size_t page_index = addr >> YUZU_PAGEBITS; std::size_t page_offset = addr & YUZU_PAGEMASK; bool user_accessible = true; - - if (!AddressSpaceContains(page_table, addr, size)) [[unlikely]] { - on_unmapped(size, addr); - return false; - } - - while (remaining_size) { - const std::size_t copy_amount = - (std::min)(static_cast(YUZU_PAGESIZE) - page_offset, remaining_size); - const auto current_vaddr = - static_cast((page_index << YUZU_PAGEBITS) + page_offset); - - const auto [pointer, type] = page_table.entries[page_index].ptr.PointerType(); + while (remaining_size != 0) { + const std::size_t copy_amount = (std::min)(std::size_t(YUZU_PAGESIZE) - page_offset, remaining_size); + const auto current_vaddr = u64((page_index << YUZU_PAGEBITS) + page_offset); + const auto [pointer, type] = current_page_table->entries[page_index].ptr.PointerType(); switch (type) { case Common::PageType::Unmapped: { user_accessible = false; - on_unmapped(copy_amount, current_vaddr); + on_unmapped(offset, copy_amount, current_vaddr); break; } case Common::PageType::Memory: { - u8* mem_ptr = - reinterpret_cast(pointer + page_offset + (page_index << YUZU_PAGEBITS)); - on_memory(copy_amount, mem_ptr); + u8* mem_ptr = reinterpret_cast(pointer + page_offset + (page_index << YUZU_PAGEBITS)); + on_memory(offset, copy_amount, mem_ptr); break; } case Common::PageType::DebugMemory: { - u8* const mem_ptr{GetPointerFromDebugMemory(current_vaddr)}; - on_memory(copy_amount, mem_ptr); + u8* const mem_ptr = GetPointerFromDebugMemory(current_vaddr); + on_memory(offset, copy_amount, mem_ptr); break; } case Common::PageType::RasterizerCachedMemory: { - u8* const host_ptr{GetPointerFromRasterizerCachedMemory(current_vaddr)}; - on_rasterizer(current_vaddr, copy_amount, host_ptr); + u8* const host_ptr = GetPointerFromRasterizerCachedMemory(current_vaddr); + on_rasterizer(current_vaddr, offset, copy_amount, host_ptr); break; } default: UNREACHABLE(); } - page_index++; page_offset = 0; - increment(copy_amount); + offset += copy_amount; remaining_size -= copy_amount; } - return user_accessible; } - template - bool ReadBlockImpl(const Common::ProcessAddress src_addr, void* dest_buffer, - const std::size_t size) { - return WalkBlock( - src_addr, size, - [src_addr, size, &dest_buffer](const std::size_t copy_amount, - const Common::ProcessAddress current_vaddr) { - LOG_ERROR(HW_Memory, - "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", - GetInteger(current_vaddr), GetInteger(src_addr), size); - std::memset(dest_buffer, 0, copy_amount); - }, - [&](const std::size_t copy_amount, const u8* const src_ptr) { - std::memcpy(dest_buffer, src_ptr, copy_amount); - }, - [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, - const u8* const host_ptr) { - if constexpr (!UNSAFE) { - HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount); - } - std::memcpy(dest_buffer, host_ptr, copy_amount); - }, - [&](const std::size_t copy_amount) { - dest_buffer = static_cast(dest_buffer) + copy_amount; - }); - } - - bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, - const std::size_t size) { - // TODO: If you want a proper multithreaded implementation (w/o cache coherency fights) - // use TBB or something that splits the job properly - return ReadBlockImpl(src_addr, dest_buffer, size); - } - - bool ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, - const std::size_t size) { - return ReadBlockImpl(src_addr, dest_buffer, size); - } - - const u8* GetSpan(const VAddr src_addr, const std::size_t size) const { - if (current_page_table->entries[src_addr >> YUZU_PAGEBITS].block == - current_page_table->entries[(src_addr + size) >> YUZU_PAGEBITS].block) { - return GetPointerSilent(src_addr); - } - return nullptr; - } - - u8* GetSpan(const VAddr src_addr, const std::size_t size) { - if (current_page_table->entries[src_addr >> YUZU_PAGEBITS].block == - current_page_table->entries[(src_addr + size) >> YUZU_PAGEBITS].block) { - return GetPointerSilent(src_addr); - } - return nullptr; - } - - template - bool WriteBlockImpl(const Common::ProcessAddress dest_addr, const void* src_buffer, - const std::size_t size) { - return WalkBlock( - dest_addr, size, - [dest_addr, size](const std::size_t copy_amount, - const Common::ProcessAddress current_vaddr) { - LOG_ERROR(HW_Memory, - "Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", - GetInteger(current_vaddr), GetInteger(dest_addr), size); - }, - [&](const std::size_t copy_amount, u8* const dest_ptr) { - std::memcpy(dest_ptr, src_buffer, copy_amount); - }, - [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, - u8* const host_ptr) { - if constexpr (!UNSAFE) { - HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount); - } - std::memcpy(host_ptr, src_buffer, copy_amount); - }, - [&](const std::size_t copy_amount) { - src_buffer = static_cast(src_buffer) + copy_amount; - }); - } - - bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, - const std::size_t size) { - // TODO: If you want a proper multithreaded implementation (w/o cache coherency fights) - // use TBB or something that splits the job properly - return WriteBlockImpl(dest_addr, src_buffer, size); - } - - bool WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, - const std::size_t size) { - return WriteBlockImpl(dest_addr, src_buffer, size); - } - - bool ZeroBlock(const Common::ProcessAddress dest_addr, const std::size_t size) { - return WalkBlock( - dest_addr, size, - [dest_addr, size](const std::size_t copy_amount, - const Common::ProcessAddress current_vaddr) { - LOG_ERROR(HW_Memory, - "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", - GetInteger(current_vaddr), GetInteger(dest_addr), size); - }, - [](const std::size_t copy_amount, u8* const dest_ptr) { - std::memset(dest_ptr, 0, copy_amount); - }, - [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, - u8* const host_ptr) { - HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount); - std::memset(host_ptr, 0, copy_amount); - }, - [](const std::size_t copy_amount) {}); - } - - bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, - const std::size_t size) { - return WalkBlock( - dest_addr, size, - [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { - LOG_ERROR(HW_Memory, - "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", - GetInteger(current_vaddr), GetInteger(src_addr), size); - ZeroBlock(dest_addr, copy_amount); - }, - [&](const std::size_t copy_amount, const u8* const src_ptr) { - WriteBlockImpl(dest_addr, src_ptr, copy_amount); - }, - [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, - u8* const host_ptr) { + bool ReadBlockImpl(const Common::ProcessAddress addr, void* buffer, const std::size_t size, bool unsafe) { + return WalkBlock(addr, size, + [addr, size, &buffer](const std::size_t offset, const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { + LOG_ERROR(HW_Memory, "Unmapped @ {:#016X} (start address = {:#016X}, size = {})", GetInteger(current_vaddr), GetInteger(addr), size); + std::memset(reinterpret_cast(buffer) + offset, 0, copy_amount); + }, + [&](const std::size_t offset, const std::size_t copy_amount, const u8* const ptr) { + std::memcpy(reinterpret_cast(buffer) + offset, ptr, copy_amount); + }, + [&](const Common::ProcessAddress current_vaddr, const std::size_t offset, const std::size_t copy_amount, const u8* const ptr) { + if (!unsafe) { HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount); - WriteBlockImpl(dest_addr, host_ptr, copy_amount); - }, - [&](const std::size_t copy_amount) { - dest_addr += copy_amount; - src_addr += copy_amount; - }); + } + std::memcpy(reinterpret_cast(buffer) + offset, ptr, copy_amount); + }); + } + + [[nodiscard]] inline const u8* GetSpan(const VAddr addr, const std::size_t size) const noexcept { + return (current_page_table->entries[addr >> YUZU_PAGEBITS].block == current_page_table->entries[(addr + size) >> YUZU_PAGEBITS].block) ? GetPointerSilent(addr) : nullptr; + } + [[nodiscard]] inline u8* GetSpan(const VAddr addr, const std::size_t size) noexcept { + return (current_page_table->entries[addr >> YUZU_PAGEBITS].block == current_page_table->entries[(addr + size) >> YUZU_PAGEBITS].block) ? GetPointerSilent(addr) : nullptr; + } + + bool WriteBlockImpl(const Common::ProcessAddress addr, const void* buffer, const std::size_t size, bool unsafe) { + return WalkBlock(addr, size, + [addr, size](const std::size_t offset, const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { + LOG_ERROR(HW_Memory, "Unmapped @ 0x{:016X} (start address = 0x{:016X}, size = {})", GetInteger(current_vaddr), GetInteger(addr), size); + }, + [&](const std::size_t offset, const std::size_t copy_amount, u8* const ptr) { + std::memcpy(ptr, reinterpret_cast(buffer) + offset, copy_amount); + }, + [&](const Common::ProcessAddress current_vaddr, const std::size_t offset, const std::size_t copy_amount, u8* const ptr) { + if (!unsafe) { + HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount); + } + std::memcpy(ptr, reinterpret_cast(buffer) + offset, copy_amount); + }); + } + + bool ZeroBlock(const Common::ProcessAddress addr, const std::size_t size) { + return WalkBlock(addr, size, + [addr, size](const std::size_t offset, const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { + LOG_ERROR(HW_Memory, "Unmapped @ {:#016X} (start address = {:#016X}, size = {})", GetInteger(current_vaddr), GetInteger(addr), size); + }, + [=](const std::size_t offset, const std::size_t copy_amount, u8* const ptr) { + std::memset(ptr, 0, copy_amount); + }, + [&](const Common::ProcessAddress current_vaddr, const std::size_t offset, const std::size_t copy_amount, u8* const ptr) { + HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount); + std::memset(ptr, 0, copy_amount); + }); + } + + bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, const std::size_t size) { + return WalkBlock(dest_addr, size, + [&](const std::size_t offset, const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { + LOG_ERROR(HW_Memory, "Unmapped @ {:#016X} (start address = {:#016X}, size = {})", GetInteger(current_vaddr), GetInteger(src_addr), size); + ZeroBlock(dest_addr + offset, copy_amount); + }, + [&](const std::size_t offset, const std::size_t copy_amount, const u8* const ptr) { + WriteBlockImpl(dest_addr + offset, ptr, copy_amount, false); + }, + [&](const Common::ProcessAddress current_vaddr, const std::size_t offset, const std::size_t copy_amount, u8* const ptr) { + HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount); + WriteBlockImpl(dest_addr + offset, ptr, copy_amount, false); + }); } template - Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size, - Callback&& cb) { - class InvalidMemoryException : public std::exception {}; - - try { - WalkBlock( - dest_addr, size, - [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) { - LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", - GetInteger(current_vaddr)); - throw InvalidMemoryException(); - }, - [&](const std::size_t block_size, u8* const host_ptr) {}, - [&](const Common::ProcessAddress current_vaddr, const std::size_t block_size, - u8* const host_ptr) { cb(current_vaddr, block_size); }, - [](const std::size_t block_size) {}); - } catch (InvalidMemoryException&) { - return Kernel::ResultInvalidCurrentMemory; - } - - return ResultSuccess; + Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size, Callback&& cb) { + bool had_unmapped = false; + WalkBlock(dest_addr, size, + [&](const std::size_t offset, const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { + LOG_ERROR(HW_Memory, "Unmapped @ {:#018X}", GetInteger(current_vaddr)); + had_unmapped = true; + }, + [](const std::size_t offset, const std::size_t copy_amount, u8* const host_ptr) {}, + [&](const Common::ProcessAddress current_vaddr, const std::size_t offset, const std::size_t copy_amount, u8* const host_ptr) { cb(current_vaddr, offset, copy_amount); } + ); + return had_unmapped ? Kernel::ResultInvalidCurrentMemory : ResultSuccess; } Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size) { - auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, - const std::size_t block_size) { + auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, const std::size_t offset, const std::size_t block_size) { // dc ivac: Invalidate to point of coherency // GPU flush -> CPU invalidate HandleRasterizerDownload(GetInteger(current_vaddr), block_size); @@ -460,8 +372,7 @@ struct Memory::Impl { } Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size) { - auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, - const std::size_t block_size) { + auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, const std::size_t offset, const std::size_t block_size) { // dc cvac: Store to point of coherency // CPU flush -> GPU invalidate HandleRasterizerWrite(GetInteger(current_vaddr), block_size); @@ -470,8 +381,7 @@ struct Memory::Impl { } Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size) { - auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, - const std::size_t block_size) { + auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, const std::size_t offset, const std::size_t block_size) { // dc civac: Store to point of coherency, and invalidate from cache // CPU flush -> GPU invalidate HandleRasterizerWrite(GetInteger(current_vaddr), block_size); @@ -487,7 +397,7 @@ struct Memory::Impl { if (current_page_table->fastmem_arena) { const auto perm{debug ? Common::MemoryPermission{} : Common::MemoryPermission::ReadWrite}; - buffer->Protect(vaddr, size, perm); + host_buffer->Protect(vaddr, size, perm); } // Iterate over a contiguous CPU address space, marking/unmarking the region. @@ -547,7 +457,7 @@ struct Memory::Impl { if (!cached) { perm |= Common::MemoryPermission::Write; } - buffer->Protect(vaddr, size, perm); + host_buffer->Protect(vaddr, size, perm); } // Iterate over a contiguous CPU address space, which corresponds to the specified GPU @@ -859,9 +769,9 @@ struct Memory::Impl { std::mutex sys_core_guard; #ifdef __ANDROID__ std::optional heap_tracker; - Common::HeapTracker* buffer{}; + Common::HeapTracker* host_buffer{}; #else - Common::HostMemory* buffer{}; + Common::HostMemory* host_buffer{}; #endif }; @@ -989,12 +899,12 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le bool Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, const std::size_t size) { - return impl->ReadBlock(src_addr, dest_buffer, size); + return impl->ReadBlockImpl(src_addr, dest_buffer, size, false); } bool Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, const std::size_t size) { - return impl->ReadBlockUnsafe(src_addr, dest_buffer, size); + return impl->ReadBlockImpl(src_addr, dest_buffer, size, true); } const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const { @@ -1007,12 +917,12 @@ u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) { bool Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, const std::size_t size) { - return impl->WriteBlock(dest_addr, src_buffer, size); + return impl->WriteBlockImpl(dest_addr, src_buffer, size, false); } bool Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, const std::size_t size) { - return impl->WriteBlockUnsafe(dest_addr, src_buffer, size); + return impl->WriteBlockImpl(dest_addr, src_buffer, size, true); } bool Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, @@ -1066,7 +976,7 @@ bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) { #ifdef __ANDROID__ if (!rasterizer && mapped) { - impl->buffer->DeferredMapSeparateHeap(GetInteger(vaddr)); + impl->host_buffer->DeferredMapSeparateHeap(GetInteger(vaddr)); } #endif @@ -1075,7 +985,7 @@ bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) { bool Memory::InvalidateSeparateHeap(void* fault_address) { #ifdef __ANDROID__ - return impl->buffer->DeferredMapSeparateHeap(static_cast(fault_address)); + return impl->host_buffer->DeferredMapSeparateHeap(static_cast(fault_address)); #else return false; #endif From 4eb082485d4d2cf96ee1debf14d1f6c5dd8ee80c Mon Sep 17 00:00:00 2001 From: lizzie Date: Mon, 18 May 2026 23:54:07 +0200 Subject: [PATCH 52/58] [video_core] fix odr violation in formatter for pixelFormat (#3504) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3504 Reviewed-by: crueter Reviewed-by: CamilleLaVey --- src/video_core/surface.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/video_core/surface.h b/src/video_core/surface.h index c659a977c1..5611dbdffa 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -5,6 +5,8 @@ #pragma once +#undef PIXEL_FORMAT_LIST + #include #include #include "common/assert.h" @@ -128,7 +130,7 @@ namespace VideoCore::Surface { PIXEL_FORMAT_ELEM(S8_UINT_D24_UNORM, 1, 1, 32) \ PIXEL_FORMAT_ELEM(D32_FLOAT_S8_UINT, 1, 1, 64) -enum class PixelFormat { +enum class PixelFormat : u32 { #define PIXEL_FORMAT_ELEM(name, ...) name, PIXEL_FORMAT_LIST #undef PIXEL_FORMAT_ELEM @@ -192,6 +194,13 @@ constexpr u32 BytesPerBlock(PixelFormat pixel_format) { return BitsPerBlock(pixel_format) / CHAR_BIT; } +} + +#include "video_core/gpu.h" +#include "video_core/textures/texture.h" + +namespace VideoCore::Surface { + SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type); bool SurfaceTargetIsLayered(SurfaceTarget target); bool SurfaceTargetIsArray(SurfaceTarget target); From e875a3196b5fc525f357b387d3cb2f283b11b8a0 Mon Sep 17 00:00:00 2001 From: lizzie Date: Mon, 18 May 2026 23:54:47 +0200 Subject: [PATCH 53/58] [core/hle/services/sockets] allow 'valid' range from [16,255] for IPv4 (#3491) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3491 Reviewed-by: Maufeat Reviewed-by: CamilleLaVey --- src/core/hle/service/sockets/bsd.cpp | 8 ++++---- src/core/hle/service/sockets/sfdnsres.cpp | 2 +- src/core/hle/service/sockets/sockets.h | 3 ++- src/core/hle/service/sockets/sockets_translate.cpp | 10 +++------- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index fd758d4915..c26f1796cc 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -629,7 +629,7 @@ Errno BSD::BindImpl(s32 fd, std::span addr) { if (!IsFileDescriptorValid(fd)) { return Errno::BADF; } - ASSERT(addr.size() == sizeof(SockAddrIn)); + ASSERT(addr.size() >= 16); auto addr_in = GetValue(addr); return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); @@ -640,7 +640,7 @@ Errno BSD::ConnectImpl(s32 fd, std::span addr) { return Errno::BADF; } - UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn)); + ASSERT(addr.size() >= 16); auto addr_in = GetValue(addr); const Errno result = Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); @@ -874,7 +874,7 @@ std::pair BSD::RecvFromImpl(s32 fd, u32 flags, std::vector& mess if (ret < 0) { addr.clear(); } else { - ASSERT(addr.size() == sizeof(SockAddrIn)); + ASSERT(addr.size() >= 16); const SockAddrIn result = Translate(addr_in); PutValue(addr, result); } @@ -899,7 +899,7 @@ std::pair BSD::SendToImpl(s32 fd, u32 flags, std::span mes Network::SockAddrIn addr_in; Network::SockAddrIn* p_addr_in = nullptr; if (!addr.empty()) { - ASSERT(addr.size() == sizeof(SockAddrIn)); + ASSERT(addr.size() >= 16); auto guest_addr_in = GetValue(addr); addr_in = Translate(guest_addr_in); p_addr_in = &addr_in; diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index f9f0ee56eb..9cd60ac240 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp @@ -238,7 +238,7 @@ static std::vector SerializeAddrInfo(const std::vector& v Append(data, static_cast(Translate(addrinfo.family))); // ai_family Append(data, static_cast(Translate(addrinfo.socket_type))); // ai_socktype Append(data, static_cast(Translate(addrinfo.protocol))); // ai_protocol - Append(data, sizeof(SockAddrIn)); // ai_addrlen + Append(data, 16); // ai_addrlen // ^ *not* sizeof(SerializedSockAddrIn), not that it matters since they're the same size // ai_addr: diff --git a/src/core/hle/service/sockets/sockets.h b/src/core/hle/service/sockets/sockets.h index b72bf53c16..7992d9822c 100644 --- a/src/core/hle/service/sockets/sockets.h +++ b/src/core/hle/service/sockets/sockets.h @@ -110,8 +110,9 @@ struct SockAddrIn { u8 family; u16 portno; std::array ip; - std::array zeroes; + std::array zeroes; }; +static_assert(sizeof(SockAddrIn) == 0x100); enum class PollEvents : u16 { // Using Pascal case because IN is a macro on Windows. diff --git a/src/core/hle/service/sockets/sockets_translate.cpp b/src/core/hle/service/sockets/sockets_translate.cpp index ea12977f62..6b93adb5ce 100644 --- a/src/core/hle/service/sockets/sockets_translate.cpp +++ b/src/core/hle/service/sockets/sockets_translate.cpp @@ -265,13 +265,9 @@ PollEvents Translate(Network::PollEvents flags) { } Network::SockAddrIn Translate(SockAddrIn value) { - if (value.len != 0 && value.len != sizeof(value) && value.len != 6) { - LOG_WARNING(Service, "Unexpected SockAddrIn len={}, expected 0, {}, or 6", - value.len, sizeof(value)); - } - + // All lengths are valid, from [0 upto 256] return { - .family = Translate(static_cast(value.family)), + .family = Translate(Domain(value.family)), .ip = value.ip, .portno = static_cast(value.portno >> 8 | value.portno << 8), }; @@ -279,7 +275,7 @@ Network::SockAddrIn Translate(SockAddrIn value) { SockAddrIn Translate(Network::SockAddrIn value) { return { - .len = sizeof(SockAddrIn), + .len = 16, .family = static_cast(Translate(value.family)), .portno = static_cast(value.portno >> 8 | value.portno << 8), .ip = value.ip, From 300a646a34b6729879e3fb71d53e625a09683bb2 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 19 May 2026 23:35:53 +0200 Subject: [PATCH 54/58] [hle] make HBLoader work, add -hlaunch option (#3981) hbloader is required to launch a bunch of shit (particularly hbmenu) however due to some restrictive metadata validation, it doesn't get recognized as an NSP file programs like hbmenu require hbloader (since it feeds them data like ConfigEntries and whatnot), launching hbmenu as-is standalone will result in a launchInit() error adds an option to launch hbmenu via command line Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3981 Reviewed-by: Maufeat Reviewed-by: crueter --- docs/user/CFW.md | 8 ++++++++ docs/user/CommandLine.md | 3 +++ src/core/hle/kernel/k_capabilities.cpp | 6 +++++- src/yuzu/main_window.cpp | 14 ++++++++++---- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/docs/user/CFW.md b/docs/user/CFW.md index ea224d3d36..8f37672eb1 100644 --- a/docs/user/CFW.md +++ b/docs/user/CFW.md @@ -9,3 +9,11 @@ At the moment of writing, we do not support CFW such as Atmosphere, due to: We do however, maintain HLE compatibility with the former mentioned CFW, applications that require Atmosphere to run will run fine in the emulator without any adjustments. If they don't run - then that's a bug! + +## Atmosphere + +Fusee Galee, the bootloader and other low-level mechanisms are not emulated at the moment. + +Having OFW is recommended, but may not be required (untested). + +Extract the contents of Atmosphere into `sdmc`. Then to launch simply use `-hlaunch` instead (orthogonal to `-qlaunch`). diff --git a/docs/user/CommandLine.md b/docs/user/CommandLine.md index 41f8d3d711..6e1f0f237c 100644 --- a/docs/user/CommandLine.md +++ b/docs/user/CommandLine.md @@ -10,6 +10,9 @@ There are two main applications, an SDL-based app (`eden-cli`) and a Qt based ap - `-u `: Select the index of the user to load as. - `-input-profile `: Specifies input profile name to use (for player #0 only). - `-qlaunch`: Launch QLaunch. +- `-hlaunch`: Launch homebrew launcher `nx-hbloader`. + - Requires a copy of Atmosphere to be extracted onto `sdmc`. + - This is a shorthand for `/sdmc/atmosphere/hbl.nsp`. - `-setup`: Launch setup applet. ## eden-cli diff --git a/src/core/hle/kernel/k_capabilities.cpp b/src/core/hle/kernel/k_capabilities.cpp index d2288c30d1..90f41dd1fc 100644 --- a/src/core/hle/kernel/k_capabilities.cpp +++ b/src/core/hle/kernel/k_capabilities.cpp @@ -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 @@ -268,7 +271,8 @@ Result KCapabilities::SetHandleTableCapability(const u32 cap) { Result KCapabilities::SetDebugFlagsCapability(const u32 cap) { // Validate. const DebugFlags pack{cap}; - R_UNLESS(pack.reserved == 0, ResultReservedUsed); + // TODO: Enabling this breaks compatibility with HBloader and such + //R_UNLESS(pack.reserved == 0, ResultReservedUsed); DebugFlags debug_capabilities{m_debug_capabilities}; debug_capabilities.allow_debug.Assign(pack.allow_debug); diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index 2bb83fa189..a43a06cd31 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -3,6 +3,7 @@ // Qt on macOS doesn't define VMA shit #include +#include "common/fs/path_util.h" #include "common/settings.h" #include "common/settings_enums.h" #include "frontend_common/settings_generator.h" @@ -635,6 +636,7 @@ MainWindow::MainWindow(bool has_broken_vulkan) QString game_path; bool should_launch_qlaunch = false; + bool should_launch_hlaunch = false; bool should_launch_setup = false; bool has_gamepath = false; bool is_fullscreen = false; @@ -676,6 +678,8 @@ MainWindow::MainWindow(bool has_broken_vulkan) players[0].profile_name = args[++i].toStdString(); } else if (args[i] == QStringLiteral("-qlaunch")) { should_launch_qlaunch = true; + } else if (args[i] == QStringLiteral("-hlaunch")) { + should_launch_hlaunch = true; } else if (args[i] == QStringLiteral("-setup")) { should_launch_setup = true; } else { @@ -694,10 +698,12 @@ MainWindow::MainWindow(bool has_broken_vulkan) } else { if (!game_path.isEmpty()) { BootGame(game_path, ApplicationAppletParameters()); - } else { - if (should_launch_qlaunch) { - LaunchFirmwareApplet(u64(Service::AM::AppletProgramId::QLaunch), std::nullopt); - } + } else if (should_launch_qlaunch) { + LaunchFirmwareApplet(u64(Service::AM::AppletProgramId::QLaunch), std::nullopt); + } else if (should_launch_hlaunch) { + std::filesystem::path const sd_dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir); + auto const hbl_path = (sd_dir / "atmosphere" / "hbl.nsp").string(); + BootGame(QString::fromStdString(hbl_path), ApplicationAppletParameters()); } } } From 937b5d6c4c728bae3f7203d10a2a374549493fd8 Mon Sep 17 00:00:00 2001 From: crueter Date: Fri, 1 May 2026 15:12:55 -0400 Subject: [PATCH 55/58] [desktop] More qt_common reorganization Ported from QML branch. Main "big" change is that EmuThread is now a shared state in QtCommon, not individually managed/passed around by GRenderWindow and MainWindow. Signed-off-by: crueter --- src/common/settings.cpp | 12 + src/common/settings.h | 2 + src/dedicated_room/CMakeLists.txt | 5 +- src/qt_common/CMakeLists.txt | 5 +- src/qt_common/config/shared_translation.cpp | 5 +- src/qt_common/qt_common.cpp | 216 ++++++++-- src/qt_common/qt_common.h | 19 +- src/qt_common/render/context.h | 107 +++++ src/qt_common/render/emu_thread.cpp | 83 ++++ src/qt_common/render/emu_thread.h | 97 +++++ src/qt_common/util/content.cpp | 92 +++- src/qt_common/util/content.h | 8 +- src/qt_common/util/game.cpp | 108 ++++- src/qt_common/util/game.h | 8 + .../util/vk.cpp} | 2 +- src/qt_common/util/vk.h | 68 +++ src/yuzu/CMakeLists.txt | 6 +- src/yuzu/bootmanager.cpp | 213 +--------- src/yuzu/bootmanager.h | 100 +---- .../configuration/addon/mod_select_dialog.cpp | 4 +- src/yuzu/configuration/configure_cpu.cpp | 3 +- src/yuzu/configuration/configure_debug.cpp | 6 +- src/yuzu/configuration/configure_dialog.cpp | 2 +- src/yuzu/configuration/configure_dialog.h | 2 +- src/yuzu/configuration/configure_graphics.cpp | 46 +- src/yuzu/configuration/configure_graphics.h | 2 +- src/yuzu/configuration/configure_per_game.cpp | 2 +- src/yuzu/configuration/configure_per_game.h | 2 +- src/yuzu/data_dialog.cpp | 19 +- src/yuzu/debugger/console.cpp | 1 - src/yuzu/game/game_card.cpp | 3 +- src/yuzu/game/game_list.cpp | 4 - src/yuzu/game/game_list.h | 2 - src/yuzu/game/game_list_worker.cpp | 7 +- src/yuzu/main_window.cpp | 396 ++++-------------- src/yuzu/main_window.h | 17 +- src/yuzu/updater/update_dialog.h | 4 +- src/yuzu/util/util.cpp | 105 ----- src/yuzu/util/util.h | 9 - src/yuzu/vk_device_info.h | 36 -- 40 files changed, 928 insertions(+), 900 deletions(-) create mode 100644 src/qt_common/render/context.h create mode 100644 src/qt_common/render/emu_thread.cpp create mode 100644 src/qt_common/render/emu_thread.h rename src/{yuzu/vk_device_info.cpp => qt_common/util/vk.cpp} (98%) create mode 100644 src/qt_common/util/vk.h delete mode 100644 src/yuzu/vk_device_info.h diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 54848c4dd1..61f9acb1e7 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -435,4 +435,16 @@ void ToggleSlowMode() { SetSpeedMode(SpeedMode::Standard); } +bool IsOpenGL() { + const auto backend = Settings::values.renderer_backend.GetValue(); + switch (backend) { + case RendererBackend::OpenGL_GLSL: + case RendererBackend::OpenGL_GLASM: + case RendererBackend::OpenGL_SPIRV: + return true; + default: + return false; + } +} + } // namespace Settings diff --git a/src/common/settings.h b/src/common/settings.h index e10f5105a1..e8877fce1e 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -863,6 +863,8 @@ bool IsFastmemEnabled(); void SetNceEnabled(bool is_64bit); bool IsNceEnabled(); +bool IsOpenGL(); + bool IsDockedMode(); float Volume(); diff --git a/src/dedicated_room/CMakeLists.txt b/src/dedicated_room/CMakeLists.txt index 36c8af5e34..ff9e458056 100644 --- a/src/dedicated_room/CMakeLists.txt +++ b/src/dedicated_room/CMakeLists.txt @@ -7,10 +7,9 @@ add_library(yuzu-room STATIC EXCLUDE_FROM_ALL yuzu_room.cpp yuzu_room.h - yuzu_room.rc -) + yuzu_room.rc) -target_link_libraries(yuzu-room PRIVATE common network) +target_link_libraries(yuzu-room PRIVATE common) if (ENABLE_WEB_SERVICE) target_compile_definitions(yuzu-room PRIVATE ENABLE_WEB_SERVICE) target_link_libraries(yuzu-room PRIVATE web_service) diff --git a/src/qt_common/CMakeLists.txt b/src/qt_common/CMakeLists.txt index 399fbe67a0..8764160af1 100644 --- a/src/qt_common/CMakeLists.txt +++ b/src/qt_common/CMakeLists.txt @@ -26,6 +26,7 @@ add_library(qt_common STATIC util/compress.h util/compress.cpp util/fs.h util/fs.cpp util/mod.h util/mod.cpp + util/vk.h util/vk.cpp abstract/frontend.h abstract/frontend.cpp abstract/progress.h abstract/progress.cpp @@ -33,7 +34,9 @@ add_library(qt_common STATIC qt_string_lookup.h qt_compat.h - discord/discord.h) + discord/discord.h + render/context.h + render/emu_thread.h render/emu_thread.cpp) if (UNIX) target_sources(qt_common PRIVATE gui_settings.cpp gui_settings.h) diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp index 506d74084f..6b8f8e73b6 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -165,8 +165,9 @@ std::unique_ptr InitializeTranslations(QObject* parent) { INSERT(Settings, use_disk_shader_cache, tr("Use persistent pipeline cache"), tr("Allows saving shaders to storage for faster loading on following game " "boots.\nDisabling it is only intended for debugging.")); - INSERT(Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"), - tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled.")); + INSERT( + Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"), + tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled.")); INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"), tr("Specifies how videos should be decoded.\nIt can either use the CPU or the GPU for " "decoding, or perform no decoding at all (black screen on videos).\n" diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp index 3091171df8..0a134d5047 100644 --- a/src/qt_common/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -1,25 +1,52 @@ // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later -#include "common/fs/fs.h" +#include "common/literals.h" + +#include "common/memory_detect.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "hid_core/hid_core.h" +#include "network/network.h" #include "qt_common.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" +#include "common/logging.h" +#include "common/scm_rev.h" +#include "core/memory.h" + +#ifdef ARCHITECTURE_x86_64 +#include "common/x64/cpu_detect.h" +#endif + #include #include -#include "common/logging.h" #include "core/frontend/emu_window.h" +#include "qt_common/util/meta.h" #include +#include + +#include #include #if !defined(WIN32) && !defined(__APPLE__) #include #elif defined(__APPLE__) #include -#include #endif +#ifdef _WIN32 +#include +#include +#include +#include "common/windows/timer_resolution.h" +#include "core/core_timing.h" +#endif + +using namespace Common::Literals; + namespace QtCommon { QWidget* rootObject = nullptr; @@ -27,6 +54,11 @@ QWidget* rootObject = nullptr; std::unique_ptr system = nullptr; std::shared_ptr vfs = nullptr; std::unique_ptr provider = nullptr; +std::unique_ptr emu_thread = nullptr; + +const QStringList supported_file_extensions = {QStringLiteral("nro"), QStringLiteral("nso"), + QStringLiteral("nca"), QStringLiteral("xci"), + QStringLiteral("nsp"), QStringLiteral("kip")}; Core::Frontend::WindowSystemType GetWindowSystemType() { // Determine WSI type based on Qt platform. @@ -58,37 +90,8 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) // Our Win32 Qt external doesn't have the private API. wsi.render_surface = reinterpret_cast(window->winId()); #elif defined(__APPLE__) - id layer = reinterpret_cast(objc_msgSend)( + wsi.render_surface = reinterpret_cast(objc_msgSend)( reinterpret_cast(window->winId()), sel_registerName("layer")); - - // In Qt 6, the layer of the NSView might be a QContainerLayer. - // MoltenVK needs a CAMetalLayer. We search for it in sublayers. - Class metal_layer_class = objc_getClass("CAMetalLayer"); - id metal_layer = nullptr; - - if (layer) { - if (reinterpret_cast(objc_msgSend)( - layer, sel_registerName("isKindOfClass:"), metal_layer_class)) { - metal_layer = layer; - } else { - id sublayers = reinterpret_cast(objc_msgSend)( - layer, sel_registerName("sublayers")); - if (sublayers) { - unsigned long count = reinterpret_cast(objc_msgSend)( - sublayers, sel_registerName("count")); - for (unsigned long i = 0; i < count; ++i) { - id sublayer = reinterpret_cast(objc_msgSend)( - sublayers, sel_registerName("objectAtIndex:"), i); - if (reinterpret_cast(objc_msgSend)( - sublayer, sel_registerName("isKindOfClass:"), metal_layer_class)) { - metal_layer = sublayer; - break; - } - } - } - } - } - wsi.render_surface = reinterpret_cast(metal_layer ? metal_layer : layer); #else QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); wsi.display_connection = pni->nativeResourceForWindow("display", window); @@ -103,18 +106,148 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) } const QString tr(const char* str) { - return QGuiApplication::tr(str); + return rootObject->tr(str); } const QString tr(const std::string& str) { - return QGuiApplication::tr(str.c_str()); + return rootObject->tr(str.c_str()); +} + +static void LogRuntimes() { +#ifdef _MSC_VER + // It is possible that the name of the dll will change. + // vcruntime140.dll is for 2015 and onwards + static constexpr char runtime_dll_name[] = "vcruntime140.dll"; + UINT sz = GetFileVersionInfoSizeA(runtime_dll_name, nullptr); + bool runtime_version_inspection_worked = false; + if (sz > 0) { + std::vector buf(sz); + if (GetFileVersionInfoA(runtime_dll_name, 0, sz, buf.data())) { + VS_FIXEDFILEINFO* pvi; + sz = sizeof(VS_FIXEDFILEINFO); + if (VerQueryValueA(buf.data(), "\\", reinterpret_cast(&pvi), &sz)) { + if (pvi->dwSignature == VS_FFI_SIGNATURE) { + runtime_version_inspection_worked = true; + LOG_INFO(Frontend, "MSVC Compiler: {} Runtime: {}.{}.{}.{}", _MSC_VER, + pvi->dwProductVersionMS >> 16, pvi->dwProductVersionMS & 0xFFFF, + pvi->dwProductVersionLS >> 16, pvi->dwProductVersionLS & 0xFFFF); + } + } + } + } + if (!runtime_version_inspection_worked) { + LOG_INFO(Frontend, "Unable to inspect {}", runtime_dll_name); + } +#endif + LOG_INFO(Frontend, "Qt Compile: {} Runtime: {}", QT_VERSION_STR, qVersion()); +} + +static QString PrettyProductName() { +#ifdef _WIN32 + // After Windows 10 Version 2004, Microsoft decided to switch to a different notation: 20H2 + // With that notation change they changed the registry key used to denote the current version + QSettings windows_registry( + QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), + QSettings::NativeFormat); + const QString release_id = windows_registry.value(QStringLiteral("ReleaseId")).toString(); + if (release_id == QStringLiteral("2009")) { + const u32 current_build = windows_registry.value(QStringLiteral("CurrentBuild")).toUInt(); + const QString display_version = + windows_registry.value(QStringLiteral("DisplayVersion")).toString(); + const u32 ubr = windows_registry.value(QStringLiteral("UBR")).toUInt(); + u32 version = 10; + if (current_build >= 22000) { + version = 11; + } + return QStringLiteral("Windows %1 Version %2 (Build %3.%4)") + .arg(QString::number(version), display_version, QString::number(current_build), + QString::number(ubr)); + } +#endif + return QSysInfo::prettyProductName(); +} + +static void RemoveCachedContents() { + const auto cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); + const auto offline_fonts = cache_dir / "fonts"; + const auto offline_manual = cache_dir / "offline_web_applet_manual"; + const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information"; + const auto offline_system_data = cache_dir / "offline_web_applet_system_data"; + + Common::FS::RemoveDirRecursively(offline_fonts); + Common::FS::RemoveDirRecursively(offline_manual); + Common::FS::RemoveDirRecursively(offline_legal_information); + Common::FS::RemoveDirRecursively(offline_system_data); } void Init(QWidget* root) { - system = std::make_unique(); rootObject = root; + + system = std::make_unique(); vfs = std::make_unique(); provider = std::make_unique(); + + // initialization stuff + Common::FS::CreateEdenPaths(); + + system->Initialize(); + + Common::Log::Initialize(); + Common::Log::Start(); + + Network::Init(); + + QtCommon::Meta::RegisterMetaTypes(); + + // build version + const auto branch_name = std::string(Common::g_scm_branch); + const auto description = std::string(Common::g_scm_desc); + const auto build_id = std::string(Common::g_build_id); + + const auto yuzu_build = fmt::format("Eden Development Build | {}-{}", branch_name, description); + const auto override_build = + fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); + const auto yuzu_build_version = override_build.empty() ? yuzu_build : override_build; + const auto processor_count = std::thread::hardware_concurrency(); + + // info logging + LOG_INFO(Frontend, "Eden Version: {}", yuzu_build_version); + LogRuntimes(); +#ifdef ARCHITECTURE_x86_64 + const auto& caps = Common::GetCPUCaps(); + std::string cpu_string = caps.cpu_string; + if (caps.avx || caps.avx2 || caps.avx512f) { + cpu_string += " | AVX"; + if (caps.avx512f) { + cpu_string += "512"; + } else if (caps.avx2) { + cpu_string += '2'; + } + if (caps.fma || caps.fma4) { + cpu_string += " | FMA"; + } + } + LOG_INFO(Frontend, "Host CPU: {}", cpu_string); + if (std::optional processor_core = Common::GetProcessorCount()) { + LOG_INFO(Frontend, "Host CPU Cores: {}", *processor_core); + } +#endif + LOG_INFO(Frontend, "Host CPU Threads: {}", processor_count); + LOG_INFO(Frontend, "Host OS: {}", PrettyProductName().toStdString()); + LOG_INFO(Frontend, "Host RAM: {:.2f} GiB", + Common::GetMemInfo().TotalPhysicalMemory / f64{1_GiB}); + LOG_INFO(Frontend, "Host Swap: {:.2f} GiB", Common::GetMemInfo().TotalSwapMemory / f64{1_GiB}); +#ifdef _WIN32 + LOG_INFO(Frontend, "Host Timer Resolution: {:.4f} ms", + std::chrono::duration_cast>( + Common::Windows::SetCurrentTimerResolutionToMaximum()) + .count()); + QtCommon::system->CoreTiming().SetTimerResolutionNs( + Common::Windows::GetCurrentTimerResolution()); +#endif + + // Remove cached contents generated during the previous session + RemoveCachedContents(); } std::filesystem::path GetEdenCommand() { @@ -137,4 +270,15 @@ std::filesystem::path GetEdenCommand() { return command; } +void SetupContentProviders() { + system->SetContentProvider(std::make_unique()); + system->RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual, + provider.get()); + system->GetFileSystemController().CreateFactories(*vfs); +} + +void SetupHID() { + system->HIDCore().ReloadInputDevices(); +} + } // namespace QtCommon diff --git a/src/qt_common/qt_common.h b/src/qt_common/qt_common.h index 19c09ef5d0..dd860ef5f7 100644 --- a/src/qt_common/qt_common.h +++ b/src/qt_common/qt_common.h @@ -6,19 +6,31 @@ #include #include -#include + #include "core/core.h" #include "core/file_sys/registered_cache.h" +#include "core/frontend/emu_window.h" -#include +#include "qt_common/render/emu_thread.h" + +#include "core/file_sys/vfs/vfs_real.h" + +enum class StartGameType { + Normal, // Can use custom configuration + Global, // Only uses global configuration +}; namespace QtCommon { +// TODO: Remove QWidget dependency extern QWidget* rootObject; extern std::unique_ptr system; extern std::shared_ptr vfs; extern std::unique_ptr provider; +extern std::unique_ptr emu_thread; + +extern const QStringList supported_file_extensions; typedef std::function QtProgressCallback; @@ -28,6 +40,9 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) void Init(QWidget* root); +void SetupContentProviders(); +void SetupHID(); + const QString tr(const char* str); const QString tr(const std::string& str); diff --git a/src/qt_common/render/context.h b/src/qt_common/render/context.h new file mode 100644 index 0000000000..a0ecade9c8 --- /dev/null +++ b/src/qt_common/render/context.h @@ -0,0 +1,107 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include "common/logging.h" +#include "common/settings.h" +#include "core/frontend/graphics_context.h" + +#ifdef HAS_OPENGL +#include +#include +#endif + +#ifdef HAS_OPENGL +class OpenGLSharedContext : public Core::Frontend::GraphicsContext { +public: + /// Create the original context that should be shared from + explicit OpenGLSharedContext(QSurface* surface_) : surface{surface_} { + QSurfaceFormat format; + format.setVersion(4, 6); + format.setProfile(QSurfaceFormat::CompatibilityProfile); + format.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions); + if (Settings::values.renderer_debug) { + format.setOption(QSurfaceFormat::FormatOption::DebugContext); + } + // TODO: expose a setting for buffer value (ie default/single/double/triple) + format.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior); + format.setSwapInterval(0); + + context = std::make_unique(); + context->setFormat(format); + if (!context->create()) { + LOG_ERROR(Frontend, "Unable to create main openGL context"); + } + } + + /// Create the shared contexts for rendering and presentation + explicit OpenGLSharedContext(QOpenGLContext* share_context, QSurface* main_surface = nullptr) { + + // disable vsync for any shared contexts + auto format = share_context->format(); + const int swap_interval = + Settings::values.vsync_mode.GetValue() == Settings::VSyncMode::Immediate ? 0 : 1; + + format.setSwapInterval(main_surface ? swap_interval : 0); + + context = std::make_unique(); + context->setShareContext(share_context); + context->setFormat(format); + if (!context->create()) { + LOG_ERROR(Frontend, "Unable to create shared openGL context"); + } + + if (!main_surface) { + offscreen_surface = std::make_unique(nullptr); + offscreen_surface->setFormat(format); + offscreen_surface->create(); + surface = offscreen_surface.get(); + } else { + surface = main_surface; + } + } + + ~OpenGLSharedContext() { + DoneCurrent(); + } + + void SwapBuffers() override { + context->swapBuffers(surface); + } + + void MakeCurrent() override { + // We can't track the current state of the underlying context in this wrapper class because + // Qt may make the underlying context not current for one reason or another. In particular, + // the WebBrowser uses GL, so it seems to conflict if we aren't careful. + // Instead of always just making the context current (which does not have any caching to + // check if the underlying context is already current) we can check for the current context + // in the thread local data by calling `currentContext()` and checking if its ours. + if (QOpenGLContext::currentContext() != context.get()) { + context->makeCurrent(surface); + } + } + + void DoneCurrent() override { + context->doneCurrent(); + } + + QOpenGLContext* GetShareContext() { + return context.get(); + } + + const QOpenGLContext* GetShareContext() const { + return context.get(); + } + +private: + // Avoid using Qt parent system here since we might move the QObjects to new threads + // As a note, this means we should avoid using slots/signals with the objects too + std::unique_ptr context; + std::unique_ptr offscreen_surface{}; + QSurface* surface; +}; +#endif + +class DummyContext : public Core::Frontend::GraphicsContext {}; diff --git a/src/qt_common/render/emu_thread.cpp b/src/qt_common/render/emu_thread.cpp new file mode 100644 index 0000000000..1b65867509 --- /dev/null +++ b/src/qt_common/render/emu_thread.cpp @@ -0,0 +1,83 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include "core/core.h" +#include "core/cpu_manager.h" +#include "emu_thread.h" +#include "qt_common/qt_common.h" +#include "video_core/gpu.h" +#include "video_core/rasterizer_interface.h" +#include "video_core/renderer_base.h" + +EmuThread::EmuThread() {} + +EmuThread::~EmuThread() = default; + +void EmuThread::run() { + Common::SetCurrentThreadName("EmuControlThread"); + + auto& gpu = QtCommon::system->GPU(); + auto stop_token = m_stop_source.get_token(); + + QtCommon::system->RegisterHostThread(); + + // Main process has been loaded. Make the context current to this thread and begin GPU and CPU + // execution. + gpu.ObtainContext(); + + emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); + if (Settings::values.use_disk_shader_cache.GetValue()) { + QtCommon::system->Renderer().ReadRasterizer()->LoadDiskResources( + QtCommon::system->GetApplicationProcessProgramID(), stop_token, + [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { + emit LoadProgress(stage, value, total); + }); + } + emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); + + gpu.ReleaseContext(); + gpu.Start(); + + QtCommon::system->GetCpuManager().OnGpuReady(); + + if (QtCommon::system->DebuggerEnabled()) { + QtCommon::system->InitializeDebugger(); + } + + while (!stop_token.stop_requested()) { + std::unique_lock lk{m_should_run_mutex}; + if (m_should_run) { + QtCommon::system->Run(); + m_stopped.Reset(); + + m_should_run_cv.wait(lk, stop_token, [&] { return !m_should_run; }); + } else { + QtCommon::system->Pause(); + m_stopped.Set(); + + EmulationPaused(lk); + m_should_run_cv.wait(lk, stop_token, [&] { return m_should_run; }); + EmulationResumed(lk); + } + } + + // Shutdown the main emulated process + QtCommon::system->DetachDebugger(); + QtCommon::system->ShutdownMainProcess(); +} + +// Unlock while emitting signals so that the main thread can +// continue pumping events. + +void EmuThread::EmulationPaused(std::unique_lock& lk) { + lk.unlock(); + emit DebugModeEntered(); + lk.lock(); +} + +void EmuThread::EmulationResumed(std::unique_lock& lk) { + lk.unlock(); + emit DebugModeLeft(); + lk.lock(); +} diff --git a/src/qt_common/render/emu_thread.h b/src/qt_common/render/emu_thread.h new file mode 100644 index 0000000000..92bae50979 --- /dev/null +++ b/src/qt_common/render/emu_thread.h @@ -0,0 +1,97 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include "common/logging.h" +#include "common/thread.h" + +namespace Core { +class System; +} // namespace Core + +namespace VideoCore { +enum class LoadCallbackStage; +} // namespace VideoCore + +class EmuThread final : public QThread { + Q_OBJECT + +public: + explicit EmuThread(); + ~EmuThread() override; + + /** + * Start emulation (on new thread) + * @warning Only call when not running! + */ + void run() override; + + /** + * Sets whether the emulation thread should run or not + * @param should_run Boolean value, set the emulation thread to running if true + */ + void SetRunning(bool should_run) { + // TODO: Prevent other threads from modifying the state until we finish. + { + // Notify the running thread to change state. + std::unique_lock run_lk{m_should_run_mutex}; + m_should_run = should_run; + m_should_run_cv.notify_one(); + } + + // Wait until paused, if pausing. + if (!should_run) { + m_stopped.Wait(); + } + } + + /** + * Check if the emulation thread is running or not + * @return True if the emulation thread is running, otherwise false + */ + bool IsRunning() const { + return m_should_run; + } + + /** + * Requests for the emulation thread to immediately stop running + */ + void ForceStop() { + LOG_WARNING(Frontend, "Force stopping EmuThread"); + m_stop_source.request_stop(); + } + +private: + void EmulationPaused(std::unique_lock& lk); + void EmulationResumed(std::unique_lock& lk); + +private: + std::stop_source m_stop_source; + std::mutex m_should_run_mutex; + std::condition_variable_any m_should_run_cv; + Common::Event m_stopped; + bool m_should_run{true}; + +signals: + /** + * Emitted when the CPU has halted execution + * + * @warning When connecting to this signal from other threads, make sure to specify either + * Qt::QueuedConnection (invoke slot within the destination object's message thread) or even + * Qt::BlockingQueuedConnection (additionally block source thread until slot returns) + */ + void DebugModeEntered(); + + /** + * Emitted right before the CPU continues execution + * + * @warning When connecting to this signal from other threads, make sure to specify either + * Qt::QueuedConnection (invoke slot within the destination object's message thread) or even + * Qt::BlockingQueuedConnection (additionally block source thread until slot returns) + */ + void DebugModeLeft(); + + void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); +}; diff --git a/src/qt_common/util/content.cpp b/src/qt_common/util/content.cpp index f705b3e00f..f22242e7f7 100644 --- a/src/qt_common/util/content.cpp +++ b/src/qt_common/util/content.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +#include "core/file_sys/card_image.h" #include "qt_common/util/content.h" #include "qt_common/util/game.h" @@ -494,5 +495,94 @@ void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir, const std::str }); } -// TODO(crueter): Port InstallFirmware et al. from QML Branch +bool CheckKeys() { + if (!ContentManager::AreKeysPresent()) { + QtCommon::Frontend::Information( + tr("Keys not installed"), + tr("Install decryption keys and restart Eden before attempting to install firmware.")); + return false; + } + + return true; +} + +void InstallFirmware() { + if (!CheckKeys()) + return; + + const QString firmware_source_location = + QtCommon::Frontend::GetExistingDirectory(tr("Select Dumped Firmware Source Location"), {}); + + if (!firmware_source_location.isEmpty()) + QtCommon::Content::InstallFirmware(firmware_source_location, false); +} + +void InstallFirmwareZip() { + if (!CheckKeys()) + return; + + const QString firmware_zip_location = QtCommon::Frontend::GetOpenFileName( + tr("Select Dumped Firmware ZIP"), {}, tr("Zipped Archives (*.zip)")); + + if (firmware_zip_location.isEmpty()) + return; + + const QString qCacheDir = QtCommon::Content::UnzipFirmwareToTmp(firmware_zip_location); + + // In this case, it has to be done recursively, since sometimes people + // will pack it into a subdirectory after dumping + if (!qCacheDir.isEmpty()) { + QtCommon::Content::InstallFirmware(qCacheDir, true); + std::error_code ec; + std::filesystem::remove_all(std::filesystem::temp_directory_path() / "eden" / "firmware", + ec); + + if (ec) { + QtCommon::Frontend::Warning( + tr("Firmware cleanup failed"), + tr("Failed to clean up extracted firmware cache.\n" + "Check write permissions in the system temp directory and try " + "again.\nOS reported error: %1") + .arg(QString::fromStdString(ec.message()))); + } + } +} + +void configureFilesystemProvider(const std::string& filepath) { + // Ensure all NCAs are registered before launching the game + const auto file = QtCommon::vfs->OpenFile(filepath, FileSys::OpenMode::Read); + if (!file) { + return; + } + + auto loader = Loader::GetLoader(*QtCommon::system, file); + if (!loader) { + return; + } + + const auto file_type = loader->GetFileType(); + if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) { + return; + } + + u64 program_id = 0; + const auto res2 = loader->ReadProgramId(program_id); + if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) { + QtCommon::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(file) + : FileSys::XCI{file}.GetSecurePartitionNSP(); + for (const auto& title : nsp->GetNCAs()) { + for (const auto& entry : title.second) { + QtCommon::provider->AddEntry(entry.first.first, entry.first.second, title.first, + entry.second->GetBaseFile()); + } + } + } +} + } // namespace QtCommon::Content diff --git a/src/qt_common/util/content.h b/src/qt_common/util/content.h index 20dacf540a..452764ef54 100644 --- a/src/qt_common/util/content.h +++ b/src/qt_common/util/content.h @@ -37,9 +37,12 @@ inline const QString GetKeyInstallResultString(FirmwareManager::KeyInstallResult } void InstallFirmware(const QString& location, bool recursive); - QString UnzipFirmwareToTmp(const QString& location); +bool CheckKeys(); +void InstallFirmware(); +void InstallFirmwareZip(); + // Keys // void InstallKeys(); @@ -54,6 +57,9 @@ void ExportDataDir(FrontendCommon::DataManager::DataDir dir, const std::string& void ImportDataDir(FrontendCommon::DataManager::DataDir dir, const std::string& user_id = "", std::function callback = {}); +// Loader // +void configureFilesystemProvider(const std::string& filepath); + // Profiles // void FixProfiles(); } // namespace QtCommon::Content diff --git a/src/qt_common/util/game.cpp b/src/qt_common/util/game.cpp index e037fdae6c..33ff32bf37 100644 --- a/src/qt_common/util/game.cpp +++ b/src/qt_common/util/game.cpp @@ -11,7 +11,6 @@ #include "qt_common/abstract/frontend.h" #include "qt_common/config/uisettings.h" #include "qt_common/qt_common.h" -#include "yuzu/util/util.h" #include #include @@ -367,6 +366,7 @@ void ResetMetadata(bool show_message) { // Uhhh // +// TODO(crueter): Make QtCommon::Shortcut // Messages in pre-defined message boxes for less code spaghetti inline constexpr bool CreateShortcutMessagesGUI(ShortcutMessages imsg, const QString& game_title) { int result = 0; @@ -533,4 +533,110 @@ void CreateHomeMenuShortcut(ShortcutTarget target) { CreateShortcut(game_path, QLaunchId, "Switch Home Menu", target, "-qlaunch", false); } +bool SaveIconToFile(const std::filesystem::path& icon_path, const QImage& image) { +#if defined(WIN32) +#pragma pack(push, 2) + struct IconDir { + WORD id_reserved; + WORD id_type; + WORD id_count; + }; + + struct IconDirEntry { + BYTE width; + BYTE height; + BYTE color_count; + BYTE reserved; + WORD planes; + WORD bit_count; + DWORD bytes_in_res; + DWORD image_offset; + }; +#pragma pack(pop) + + const QImage source_image = image.convertToFormat(QImage::Format_RGB32); + constexpr std::array scale_sizes{256, 128, 64, 48, 32, 24, 16}; + constexpr int bytes_per_pixel = 4; + + const IconDir icon_dir{ + .id_reserved = 0, + .id_type = 1, + .id_count = static_cast(scale_sizes.size()), + }; + + Common::FS::IOFile icon_file(icon_path.string(), Common::FS::FileAccessMode::Write, + Common::FS::FileType::BinaryFile); + if (!icon_file.IsOpen()) { + return false; + } + + if (!icon_file.Write(icon_dir)) { + return false; + } + + std::size_t image_offset = sizeof(IconDir) + (sizeof(IconDirEntry) * scale_sizes.size()); + for (std::size_t i = 0; i < scale_sizes.size(); i++) { + const int image_size = scale_sizes[i] * scale_sizes[i] * bytes_per_pixel; + const IconDirEntry icon_entry{ + .width = static_cast(scale_sizes[i]), + .height = static_cast(scale_sizes[i]), + .color_count = 0, + .reserved = 0, + .planes = 1, + .bit_count = bytes_per_pixel * 8, + .bytes_in_res = static_cast(sizeof(BITMAPINFOHEADER) + image_size), + .image_offset = static_cast(image_offset), + }; + image_offset += icon_entry.bytes_in_res; + if (!icon_file.Write(icon_entry)) { + return false; + } + } + + for (std::size_t i = 0; i < scale_sizes.size(); i++) { + const QImage scaled_image = source_image.scaled( + scale_sizes[i], scale_sizes[i], Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + const BITMAPINFOHEADER info_header{ + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = scaled_image.width(), + .biHeight = scaled_image.height() * 2, + .biPlanes = 1, + .biBitCount = bytes_per_pixel * 8, + .biCompression = BI_RGB, + .biSizeImage{}, + .biXPelsPerMeter{}, + .biYPelsPerMeter{}, + .biClrUsed{}, + .biClrImportant{}, + }; + + if (!icon_file.Write(info_header)) { + return false; + } + + for (int y = 0; y < scaled_image.height(); y++) { + const auto* line = scaled_image.scanLine(scaled_image.height() - 1 - y); + std::vector line_data(scaled_image.width() * bytes_per_pixel); + std::memcpy(line_data.data(), line, line_data.size()); + if (!icon_file.Write(line_data)) { + return false; + } + } + } + icon_file.Close(); + + return true; +#elif defined(__unix__) && !defined(__APPLE__) && !defined(__ANDROID__) + // Convert and write the icon as a PNG + if (!image.save(QString::fromStdString(icon_path.string()))) { + LOG_ERROR(Frontend, "Could not write icon as PNG to file"); + } else { + LOG_INFO(Frontend, "Wrote an icon to {}", icon_path.string()); + } + return true; +#else + return false; +#endif +} + } // namespace QtCommon::Game diff --git a/src/qt_common/util/game.h b/src/qt_common/util/game.h index 0d7f03fa86..9a61bb9349 100644 --- a/src/qt_common/util/game.h +++ b/src/qt_common/util/game.h @@ -69,6 +69,14 @@ void CreateShortcut(const std::string& game_path, const u64 program_id, std::string GetShortcutPath(ShortcutTarget target); void CreateHomeMenuShortcut(ShortcutTarget target); +/** + * Saves a windows icon to a file + * @param path The icons path + * @param image The image to save + * @return bool If the operation succeeded + */ +[[nodiscard]] bool SaveIconToFile(const std::filesystem::path& icon_path, const QImage& image); + } // namespace QtCommon::Game #endif // QT_GAME_UTIL_H diff --git a/src/yuzu/vk_device_info.cpp b/src/qt_common/util/vk.cpp similarity index 98% rename from src/yuzu/vk_device_info.cpp rename to src/qt_common/util/vk.cpp index 1e8e140d77..8ca7f4a665 100644 --- a/src/yuzu/vk_device_info.cpp +++ b/src/qt_common/util/vk.cpp @@ -11,13 +11,13 @@ #include "common/dynamic_library.h" #include "common/logging.h" +#include "qt_common/util/vk.h" #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_instance.h" #include "video_core/vulkan_common/vulkan_library.h" #include "video_core/vulkan_common/vulkan_surface.h" #include "video_core/vulkan_common/vulkan_wrapper.h" #include "vulkan/vulkan_core.h" -#include "yuzu/vk_device_info.h" class QWindow; diff --git a/src/qt_common/util/vk.h b/src/qt_common/util/vk.h new file mode 100644 index 0000000000..73f2b6ef82 --- /dev/null +++ b/src/qt_common/util/vk.h @@ -0,0 +1,68 @@ +// SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include "common/common_types.h" +#include "common/settings_enums.h" +#include "vulkan/vulkan_core.h" + +static const std::vector default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR, + VK_PRESENT_MODE_FIFO_KHR}; + +// Converts a setting to a present mode (or vice versa) +static inline constexpr VkPresentModeKHR VSyncSettingToMode(Settings::VSyncMode mode) { + switch (mode) { + case Settings::VSyncMode::Immediate: + return VK_PRESENT_MODE_IMMEDIATE_KHR; + case Settings::VSyncMode::Mailbox: + return VK_PRESENT_MODE_MAILBOX_KHR; + case Settings::VSyncMode::Fifo: + return VK_PRESENT_MODE_FIFO_KHR; + case Settings::VSyncMode::FifoRelaxed: + return VK_PRESENT_MODE_FIFO_RELAXED_KHR; + default: + return VK_PRESENT_MODE_FIFO_KHR; + } +} + +static inline constexpr Settings::VSyncMode PresentModeToSetting(VkPresentModeKHR mode) { + switch (mode) { + case VK_PRESENT_MODE_IMMEDIATE_KHR: + return Settings::VSyncMode::Immediate; + case VK_PRESENT_MODE_MAILBOX_KHR: + return Settings::VSyncMode::Mailbox; + case VK_PRESENT_MODE_FIFO_KHR: + return Settings::VSyncMode::Fifo; + case VK_PRESENT_MODE_FIFO_RELAXED_KHR: + return Settings::VSyncMode::FifoRelaxed; + default: + return Settings::VSyncMode::Fifo; + } +} + +class QWindow; + +namespace Settings { +enum class VSyncMode : u32; +} + +namespace VkDeviceInfo { +// Short class to record Vulkan driver information for configuration purposes +class Record { +public: + explicit Record(std::string_view name, const std::vector& vsync_modes, + bool has_broken_compute); + ~Record(); + + const std::string name; + const std::vector vsync_support; + const bool has_broken_compute; +}; + +// TODO(crueter): Port some configure_graphics.cpp stuff +void PopulateRecords(std::vector& records, QWindow* window); +} // namespace VkDeviceInfo diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 7468c06c06..0bddcca3e8 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -217,8 +217,6 @@ add_executable(yuzu util/url_request_interceptor.h util/util.cpp util/util.h - vk_device_info.cpp - vk_device_info.h compatdb.cpp compatdb.h user_data_migration.cpp @@ -245,9 +243,7 @@ add_executable(yuzu render/performance_overlay.h render/performance_overlay.cpp render/performance_overlay.ui libqt_common.h libqt_common.cpp - updater/update_dialog.h updater/update_dialog.cpp updater/update_dialog.ui - -) + updater/update_dialog.h updater/update_dialog.cpp updater/update_dialog.ui) set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden") diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index dd55034e4e..074b2360ee 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -6,8 +6,6 @@ #include #include #include -#include -#include #ifdef HAS_OPENGL #include @@ -45,16 +43,13 @@ #include #endif -#include "common/polyfill_thread.h" #include "common/scm_rev.h" #include "common/settings.h" #include "common/settings_input.h" -#include "common/thread.h" #include "core/core.h" #include "core/cpu_manager.h" #include "core/frontend/framebuffer_layout.h" #include "core/frontend/graphics_context.h" -#include "input_common/drivers/camera.h" #include "input_common/drivers/keyboard.h" #include "input_common/drivers/mouse.h" #include "input_common/drivers/tas_input.h" @@ -62,189 +57,19 @@ #include "input_common/main.h" #include "qt_common/qt_common.h" #include "video_core/gpu.h" -#include "video_core/rasterizer_interface.h" #include "video_core/renderer_base.h" #include "yuzu/bootmanager.h" #include "yuzu/main_window.h" +#include "qt_common/render/context.h" +#include "qt_common/render/emu_thread.h" + class QObject; class QPaintEngine; class QSurface; constexpr int default_mouse_constrain_timeout = 10; -EmuThread::EmuThread(Core::System& system) : m_system{system} {} - -EmuThread::~EmuThread() = default; - -void EmuThread::run() { - Common::SetCurrentThreadName("EmuControlThread"); - - auto& gpu = m_system.GPU(); - auto stop_token = m_stop_source.get_token(); - - m_system.RegisterHostThread(); - - // Main process has been loaded. Make the context current to this thread and begin GPU and CPU - // execution. - gpu.ObtainContext(); - - emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); - if (Settings::values.use_disk_shader_cache.GetValue()) { - m_system.Renderer().ReadRasterizer()->LoadDiskResources( - m_system.GetApplicationProcessProgramID(), stop_token, - [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { - emit LoadProgress(stage, value, total); - }); - } - emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); - - gpu.ReleaseContext(); - gpu.Start(); - - m_system.GetCpuManager().OnGpuReady(); - - if (m_system.DebuggerEnabled()) { - m_system.InitializeDebugger(); - } - - while (!stop_token.stop_requested()) { - std::unique_lock lk{m_should_run_mutex}; - if (m_should_run) { - m_system.Run(); - m_stopped.Reset(); - - m_should_run_cv.wait(lk, stop_token, [&] { return !m_should_run; }); - } else { - m_system.Pause(); - m_stopped.Set(); - - EmulationPaused(lk); - m_should_run_cv.wait(lk, stop_token, [&] { return m_should_run; }); - EmulationResumed(lk); - } - } - - // Shutdown the main emulated process - m_system.DetachDebugger(); - m_system.ShutdownMainProcess(); -} - -// Unlock while emitting signals so that the main thread can -// continue pumping events. - -void EmuThread::EmulationPaused(std::unique_lock& lk) { - lk.unlock(); - emit DebugModeEntered(); - lk.lock(); -} - -void EmuThread::EmulationResumed(std::unique_lock& lk) { - lk.unlock(); - emit DebugModeLeft(); - lk.lock(); -} - -#ifdef HAS_OPENGL -class OpenGLSharedContext : public Core::Frontend::GraphicsContext { -public: - /// Create the original context that should be shared from - explicit OpenGLSharedContext(QSurface* surface_) : surface{surface_} { - QSurfaceFormat format; - format.setVersion(4, 6); - format.setProfile(QSurfaceFormat::CompatibilityProfile); - format.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions); - if (Settings::values.renderer_debug) { - format.setOption(QSurfaceFormat::FormatOption::DebugContext); - } - // TODO: expose a setting for buffer value (ie default/single/double/triple) - format.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior); - format.setSwapInterval(0); - - context = std::make_unique(); - context->setFormat(format); - if (!context->create()) { - LOG_ERROR(Frontend, "Unable to create main openGL context"); - } - } - - /// Create the shared contexts for rendering and presentation - explicit OpenGLSharedContext(QOpenGLContext* share_context, QSurface* main_surface = nullptr) { - - // disable vsync for any shared contexts - auto format = share_context->format(); - const int swap_interval = - Settings::values.vsync_mode.GetValue() == Settings::VSyncMode::Immediate ? 0 : 1; - - format.setSwapInterval(main_surface ? swap_interval : 0); - - context = std::make_unique(); - context->setShareContext(share_context); - context->setFormat(format); - if (!context->create()) { - LOG_ERROR(Frontend, "Unable to create shared openGL context"); - } - - if (!main_surface) { - offscreen_surface = std::make_unique(nullptr); - offscreen_surface->setFormat(format); - offscreen_surface->create(); - surface = offscreen_surface.get(); - } else { - surface = main_surface; - } - } - - ~OpenGLSharedContext() { - DoneCurrent(); - } - - void SwapBuffers() override { - if (auto window = static_cast(surface)) { - if (!window->isExposed()) { - LOG_DEBUG(Frontend, "SwapBuffers ignored: window not exposed"); - return; - } - } - - context->swapBuffers(surface); - } - - void MakeCurrent() override { - // We can't track the current state of the underlying context in this wrapper class because - // Qt may make the underlying context not current for one reason or another. In particular, - // the WebBrowser uses GL, so it seems to conflict if we aren't careful. - // Instead of always just making the context current (which does not have any caching to - // check if the underlying context is already current) we can check for the current context - // in the thread local data by calling `currentContext()` and checking if its ours. - if (QOpenGLContext::currentContext() != context.get()) { - context->makeCurrent(surface); - } - } - - void DoneCurrent() override { - context->doneCurrent(); - } - - QOpenGLContext* GetShareContext() { - return context.get(); - } - - const QOpenGLContext* GetShareContext() const { - return context.get(); - } - -private: - // Avoid using Qt parent system here since we might move the QObjects to new threads - // As a note, this means we should avoid using slots/signals with the objects too - std::unique_ptr context; - std::unique_ptr offscreen_surface{}; - QSurface* surface; -}; -#endif - -class DummyContext : public Core::Frontend::GraphicsContext {}; - class RenderWidget : public QWidget { public: explicit RenderWidget(GRenderWindow* parent) : QWidget(parent) { @@ -285,11 +110,9 @@ struct NullRenderWidget : public RenderWidget { explicit NullRenderWidget(GRenderWindow* parent) : RenderWidget(parent) {} }; -GRenderWindow::GRenderWindow(MainWindow* parent, EmuThread* emu_thread_, - std::shared_ptr input_subsystem_, - Core::System& system_) - : QWidget(parent), emu_thread(emu_thread_), input_subsystem{std::move(input_subsystem_)}, - system{system_} { +GRenderWindow::GRenderWindow(MainWindow* parent, + std::shared_ptr input_subsystem_) + : QWidget(parent), input_subsystem{std::move(input_subsystem_)} { setWindowTitle(QStringLiteral("Eden %1 | %2-%3") .arg(QString::fromUtf8(Common::g_build_name), QString::fromUtf8(Common::g_scm_branch), @@ -708,10 +531,11 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { } void GRenderWindow::ConstrainMouse() { - if (emu_thread == nullptr || !Settings::values.mouse_panning) { + if (QtCommon::emu_thread == nullptr || !Settings::values.mouse_panning) { mouse_constrain_timer.stop(); return; } + if (!this->isActiveWindow()) { mouse_constrain_timer.stop(); return; @@ -964,7 +788,7 @@ void GRenderWindow::ReleaseRenderTarget() { } void GRenderWindow::CaptureScreenshot(const QString& screenshot_path) { - auto& renderer = system.Renderer(); + auto& renderer = QtCommon::system->Renderer(); if (renderer.IsScreenshotPending()) { LOG_WARNING(Render, @@ -989,7 +813,12 @@ void GRenderWindow::CaptureScreenshot(const QString& screenshot_path) { screenshot_image.bits(), [=, this](bool invert_y) { const std::string std_screenshot_path = screenshot_path.toStdString(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) + if (screenshot_image.flipped(invert_y ? Qt::Vertical : (Qt::Orientations)0) + .save(screenshot_path)) { +#else if (screenshot_image.mirrored(false, invert_y).save(screenshot_path)) { +#endif LOG_INFO(Frontend, "Screenshot saved to \"{}\"", std_screenshot_path); } else { LOG_ERROR(Frontend, "Failed to save screenshot to \"{}\"", std_screenshot_path); @@ -1026,7 +855,8 @@ bool GRenderWindow::InitializeOpenGL() { return true; #else - QMessageBox::warning(this, tr("OpenGL not available!"), tr("Eden has not been compiled with OpenGL support.")); + QMessageBox::warning(this, tr("OpenGL not available!"), + tr("Eden has not been compiled with OpenGL support.")); return false; #endif } @@ -1072,8 +902,7 @@ bool GRenderWindow::LoadOpenGL() { tr("Your GPU may not support one or more required OpenGL extensions. Please ensure you " "have the latest graphics driver.

GL Renderer:
%1

Unsupported " "extensions:
%2") - .arg(renderer) - .arg(missing_ext.join(QStringLiteral("
")))); + .arg(renderer, missing_ext.join(QStringLiteral("
")))); // Non fatal } return true; @@ -1101,14 +930,6 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const { return missing_ext; } -void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread_) { - emu_thread = emu_thread_; -} - -void GRenderWindow::OnEmulationStopping() { - emu_thread = nullptr; -} - void GRenderWindow::showEvent(QShowEvent* event) { QWidget::showEvent(event); diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index e763cd9868..1ed61a8191 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -6,12 +6,9 @@ #pragma once -#include #include #include -#include #include -#include #include #include @@ -27,9 +24,6 @@ #include #include "common/common_types.h" -#include "common/logging.h" -#include "common/polyfill_thread.h" -#include "common/thread.h" #include "core/frontend/emu_window.h" class MainWindow; @@ -46,6 +40,7 @@ class QShowEvent; class QTouchEvent; class QWheelEvent; +class EmuThread; namespace Core { class System; } // namespace Core @@ -63,96 +58,12 @@ namespace VideoCore { enum class LoadCallbackStage; } // namespace VideoCore -class EmuThread final : public QThread { - Q_OBJECT - -public: - explicit EmuThread(Core::System& system); - ~EmuThread() override; - - /** - * Start emulation (on new thread) - * @warning Only call when not running! - */ - void run() override; - - /** - * Sets whether the emulation thread should run or not - * @param should_run Boolean value, set the emulation thread to running if true - */ - void SetRunning(bool should_run) { - // TODO: Prevent other threads from modifying the state until we finish. - { - // Notify the running thread to change state. - std::unique_lock run_lk{m_should_run_mutex}; - m_should_run = should_run; - m_should_run_cv.notify_one(); - } - - // Wait until paused, if pausing. - if (!should_run) { - m_stopped.Wait(); - } - } - - /** - * Check if the emulation thread is running or not - * @return True if the emulation thread is running, otherwise false - */ - bool IsRunning() const { - return m_should_run; - } - - /** - * Requests for the emulation thread to immediately stop running - */ - void ForceStop() { - LOG_WARNING(Frontend, "Force stopping EmuThread"); - m_stop_source.request_stop(); - } - -private: - void EmulationPaused(std::unique_lock& lk); - void EmulationResumed(std::unique_lock& lk); - -private: - Core::System& m_system; - - std::stop_source m_stop_source; - std::mutex m_should_run_mutex; - std::condition_variable_any m_should_run_cv; - Common::Event m_stopped; - bool m_should_run{true}; - -signals: - /** - * Emitted when the CPU has halted execution - * - * @warning When connecting to this signal from other threads, make sure to specify either - * Qt::QueuedConnection (invoke slot within the destination object's message thread) or even - * Qt::BlockingQueuedConnection (additionally block source thread until slot returns) - */ - void DebugModeEntered(); - - /** - * Emitted right before the CPU continues execution - * - * @warning When connecting to this signal from other threads, make sure to specify either - * Qt::QueuedConnection (invoke slot within the destination object's message thread) or even - * Qt::BlockingQueuedConnection (additionally block source thread until slot returns) - */ - void DebugModeLeft(); - - void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); -}; - class GRenderWindow : public QWidget, public Core::Frontend::EmuWindow { Q_OBJECT public: - explicit GRenderWindow(MainWindow* parent, EmuThread* emu_thread_, - std::shared_ptr input_subsystem_, - Core::System& system_); + explicit GRenderWindow(MainWindow* parent, + std::shared_ptr input_subsystem_); ~GRenderWindow() override; // EmuWindow implementation. @@ -217,8 +128,6 @@ public: void Exit(); public slots: - void OnEmulationStarting(EmuThread* emu_thread_); - void OnEmulationStopping(); void OnFramebufferSizeChanged(); signals: @@ -247,7 +156,6 @@ private: bool LoadOpenGL(); QStringList GetUnsupportedGLExtensions() const; - EmuThread* emu_thread; std::shared_ptr input_subsystem; // Main context that will be shared with all other contexts that are requested. @@ -277,8 +185,6 @@ private: QTimer mouse_constrain_timer; - Core::System& system; - protected: void showEvent(QShowEvent* event) override; bool eventFilter(QObject* object, QEvent* event) override; diff --git a/src/yuzu/configuration/addon/mod_select_dialog.cpp b/src/yuzu/configuration/addon/mod_select_dialog.cpp index 49f556a66a..f025a3b390 100644 --- a/src/yuzu/configuration/addon/mod_select_dialog.cpp +++ b/src/yuzu/configuration/addon/mod_select_dialog.cpp @@ -33,8 +33,8 @@ ModSelectDialog::ModSelectDialog(const QStringList& mods, QWidget* parent) ui->treeView->expandAll(); int rows = item_model->rowCount(); - int height = - 4 + ui->treeView->contentsMargins().top() * 4 + ui->treeView->contentsMargins().bottom() * 4; + int height = 4 + ui->treeView->contentsMargins().top() * 4 + + ui->treeView->contentsMargins().bottom() * 4; int width = 0; for (int i = 0; i < rows; ++i) { diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp index b31ca849a6..0511465ee6 100644 --- a/src/yuzu/configuration/configure_cpu.cpp +++ b/src/yuzu/configuration/configure_cpu.cpp @@ -76,7 +76,8 @@ void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) { } else if (setting->Id() == Settings::values.cpu_backend.Id()) { backend_layout->addWidget(widget); backend_combobox = widget->combobox; - } else if (setting->Id() == Settings::values.fast_cpu_time.Id() || setting->Id() == Settings::values.cpu_ticks.Id()) { + } else if (setting->Id() == Settings::values.fast_cpu_time.Id() || + setting->Id() == Settings::values.cpu_ticks.Id()) { ui->general_layout->addWidget(widget); } else { // Presently, all other settings here are unsafe checkboxes diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 9db48c084b..c7ca85ce99 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -51,8 +51,10 @@ void ConfigureDebug::SetConfiguration() { ui->enable_all_controllers->setChecked(Settings::values.enable_all_controllers.GetValue()); ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue()); ui->perform_vulkan_check->setChecked(Settings::values.perform_vulkan_check.GetValue()); - ui->serial_battery_edit->setText(QString::fromStdString(std::to_string(Settings::values.serial_battery.GetValue()))); - ui->serial_board_edit->setText(QString::fromStdString(std::to_string(Settings::values.serial_unit.GetValue()))); + ui->serial_battery_edit->setText( + QString::fromStdString(std::to_string(Settings::values.serial_battery.GetValue()))); + ui->serial_board_edit->setText( + QString::fromStdString(std::to_string(Settings::values.serial_unit.GetValue()))); #ifdef YUZU_USE_QT_WEB_ENGINE ui->disable_web_applet->setChecked(Settings::values.disable_web_applet.GetValue()); #else diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index d4a16e9f73..547008262e 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -10,8 +10,8 @@ #include "common/settings_enums.h" #include "core/core.h" #include "qt_common/config/uisettings.h" +#include "qt_common/util/vk.h" #include "ui_configure.h" -#include "vk_device_info.h" #include "yuzu/configuration/configure_applets.h" #include "yuzu/configuration/configure_audio.h" #include "yuzu/configuration/configure_cpu.h" diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index 5c504c9a16..73db11238e 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h @@ -11,8 +11,8 @@ #include #include "configuration/shared_widget.h" #include "qt_common/config/shared_translation.h" +#include "qt_common/util/vk.h" #include "yuzu/configuration/configuration_shared.h" -#include "yuzu/vk_device_info.h" namespace Core { class System; diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 54835aea5a..344cbe2406 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -4,14 +4,7 @@ // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include #include -#include -#include -#include -#include -#include -#include #include #include #include @@ -34,52 +27,15 @@ #include #include "common/common_types.h" -#include "common/dynamic_library.h" -#include "common/logging.h" #include "common/settings.h" #include "common/settings_enums.h" #include "core/core.h" #include "qt_common/config/uisettings.h" -#include "qt_common/qt_common.h" +#include "qt_common/util/vk.h" #include "ui_configure_graphics.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_graphics.h" #include "yuzu/configuration/shared_widget.h" -#include "yuzu/vk_device_info.h" - -static const std::vector default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR, - VK_PRESENT_MODE_FIFO_KHR}; - -// Converts a setting to a present mode (or vice versa) -static constexpr VkPresentModeKHR VSyncSettingToMode(Settings::VSyncMode mode) { - switch (mode) { - case Settings::VSyncMode::Immediate: - return VK_PRESENT_MODE_IMMEDIATE_KHR; - case Settings::VSyncMode::Mailbox: - return VK_PRESENT_MODE_MAILBOX_KHR; - case Settings::VSyncMode::Fifo: - return VK_PRESENT_MODE_FIFO_KHR; - case Settings::VSyncMode::FifoRelaxed: - return VK_PRESENT_MODE_FIFO_RELAXED_KHR; - default: - return VK_PRESENT_MODE_FIFO_KHR; - } -} - -static constexpr Settings::VSyncMode PresentModeToSetting(VkPresentModeKHR mode) { - switch (mode) { - case VK_PRESENT_MODE_IMMEDIATE_KHR: - return Settings::VSyncMode::Immediate; - case VK_PRESENT_MODE_MAILBOX_KHR: - return Settings::VSyncMode::Mailbox; - case VK_PRESENT_MODE_FIFO_KHR: - return Settings::VSyncMode::Fifo; - case VK_PRESENT_MODE_FIFO_RELAXED_KHR: - return Settings::VSyncMode::FifoRelaxed; - default: - return Settings::VSyncMode::Fifo; - } -} ConfigureGraphics::ConfigureGraphics( const Core::System& system_, std::vector& records_, diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index 3009edf4b6..9241a8d6df 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h @@ -19,7 +19,7 @@ #include "common/common_types.h" #include "common/settings_enums.h" #include "qt_common/config/shared_translation.h" -#include "vk_device_info.h" +#include "qt_common/util/vk.h" #include "yuzu/configuration/configuration_shared.h" class QPushButton; diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index dcf40d678f..f84448dd29 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -30,6 +30,7 @@ #include "core/loader/loader.h" #include "frontend_common/config.h" #include "qt_common/config/uisettings.h" +#include "qt_common/util/vk.h" #include "ui_configure_per_game.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_applets.h" @@ -44,7 +45,6 @@ #include "yuzu/configuration/configure_per_game_addons.h" #include "yuzu/configuration/configure_system.h" #include "yuzu/util/util.h" -#include "yuzu/vk_device_info.h" ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, std::vector& vk_device_records, diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index ca973db8b0..bc6561235e 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h @@ -18,7 +18,7 @@ #include "frontend_common/config.h" #include "qt_common/config/qt_config.h" #include "qt_common/config/shared_translation.h" -#include "vk_device_info.h" +#include "qt_common/util/vk.h" #include "yuzu/configuration/configuration_shared.h" namespace Core { diff --git a/src/yuzu/data_dialog.cpp b/src/yuzu/data_dialog.cpp index 8d50843eb3..ffdedcf1c2 100644 --- a/src/yuzu/data_dialog.cpp +++ b/src/yuzu/data_dialog.cpp @@ -63,27 +63,31 @@ DataWidget::DataWidget(FrontendCommon::DataManager::DataDir data_dir, void DataWidget::clear() { std::optional user_id = selectProfile(); - if (!user_id) return; + if (!user_id) + return; QtCommon::Content::ClearDataDir(m_dir, user_id.value()); scan(); } void DataWidget::open() { std::optional user_id = selectProfile(); - if (!user_id) return; - QDesktopServices::openUrl(QUrl::fromLocalFile( - QString::fromStdString(FrontendCommon::DataManager::GetDataDirString(m_dir, user_id.value())))); + if (!user_id) + return; + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString( + FrontendCommon::DataManager::GetDataDirString(m_dir, user_id.value())))); } void DataWidget::upload() { std::optional user_id = selectProfile(); - if (!user_id) return; + if (!user_id) + return; QtCommon::Content::ExportDataDir(m_dir, user_id.value(), m_exportName); } void DataWidget::download() { std::optional user_id = selectProfile(); - if (!user_id) return; + if (!user_id) + return; QtCommon::Content::ImportDataDir(m_dir, user_id.value(), std::bind(&DataWidget::scan, this)); } @@ -107,7 +111,8 @@ std::optional DataWidget::selectProfile() { std::string user_id{}; if (m_dir == FrontendCommon::DataManager::DataDir::Saves) { user_id = GetProfileIDString(); - if (user_id.empty()) return std::nullopt; + if (user_id.empty()) + return std::nullopt; } return user_id; diff --git a/src/yuzu/debugger/console.cpp b/src/yuzu/debugger/console.cpp index 8965c7a08f..3506f1edf3 100644 --- a/src/yuzu/debugger/console.cpp +++ b/src/yuzu/debugger/console.cpp @@ -11,7 +11,6 @@ #endif #include "common/logging.h" -#include "yuzu/debugger/console.h" #include "qt_common/config/uisettings.h" #include "yuzu/debugger/console.h" diff --git a/src/yuzu/game/game_card.cpp b/src/yuzu/game/game_card.cpp index 05167fe455..03c71449f8 100644 --- a/src/yuzu/game/game_card.cpp +++ b/src/yuzu/game/game_card.cpp @@ -36,7 +36,8 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, const auto x_pos = option.rect.left() - (column * cell_width) + static_cast(relative_x); // also, add some additional padding here to prevent card overlap - QRect cardRect(x_pos + 4, option.rect.top() + 4, fixed_card_width - 8, option.rect.height() - margins); + QRect cardRect(x_pos + 4, option.rect.top() + 4, fixed_card_width - 8, + option.rect.height() - margins); // colors QPalette palette = option.palette; diff --git a/src/yuzu/game/game_list.cpp b/src/yuzu/game/game_list.cpp index 87b5f87474..b5967bacca 100644 --- a/src/yuzu/game/game_list.cpp +++ b/src/yuzu/game/game_list.cpp @@ -1113,10 +1113,6 @@ void GameList::LoadInterfaceLayout() { header->resizeSection(COLUMN_NAME, 840); } -const QStringList GameList::supported_file_extensions = { - QStringLiteral("nso"), QStringLiteral("nro"), QStringLiteral("nca"), - QStringLiteral("xci"), QStringLiteral("nsp"), QStringLiteral("kip")}; - void GameList::RefreshGameDirectory() { // Reset the externals watcher whenever the game list is reloaded, // primarily ensures that new titles and external dirs are caught. diff --git a/src/yuzu/game/game_list.h b/src/yuzu/game/game_list.h index 42efcbdc3b..6cf857c4e1 100644 --- a/src/yuzu/game/game_list.h +++ b/src/yuzu/game/game_list.h @@ -95,8 +95,6 @@ public: /// Disables events from the emulated controller void UnloadController(); - static const QStringList supported_file_extensions; - bool IsTreeMode(); void ResetViewMode(); diff --git a/src/yuzu/game/game_list_worker.cpp b/src/yuzu/game/game_list_worker.cpp index 777122e135..df3560a813 100644 --- a/src/yuzu/game/game_list_worker.cpp +++ b/src/yuzu/game/game_list_worker.cpp @@ -20,17 +20,18 @@ #include "common/settings.h" #include "core/core.h" #include "core/file_sys/card_image.h" -#include "core/file_sys/common_funcs.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/nca_metadata.h" #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" -#include "core/file_sys/romfs.h" #include "core/file_sys/submission_package.h" #include "core/loader/loader.h" + #include "qt_common/config/uisettings.h" +#include "qt_common/qt_common.h" + #include "yuzu/compatibility_list.h" #include "yuzu/game/game_list.h" #include "yuzu/game/game_list_p.h" @@ -148,7 +149,7 @@ void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager, const bool HasSupportedFileExtension(const std::string& file_name) { const QFileInfo file = QFileInfo(QString::fromStdString(file_name)); - return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); + return QtCommon::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); } bool IsExtractedNCAMain(const std::string& file_name) { diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index a43a06cd31..3ca4b40a6d 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -2,17 +2,17 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Qt on macOS doesn't define VMA shit +#if defined(QT_STATICPLUGIN) && !defined(__APPLE__) +#undef VMA_IMPLEMENTATION +#endif + #include #include "common/fs/path_util.h" #include "common/settings.h" #include "common/settings_enums.h" #include "frontend_common/settings_generator.h" -#include "qt_common/qt_string_lookup.h" #include "render/performance_overlay.h" #include "updater/update_dialog.h" -#if defined(QT_STATICPLUGIN) && !defined(__APPLE__) -#undef VMA_IMPLEMENTATION -#endif #include "common/fs/ryujinx_compat.h" #include "main_window.h" @@ -31,10 +31,10 @@ #include "bootmanager.h" #include "loading_screen.h" +#include "qt_common/util/vk.h" #include "ryujinx_dialog.h" #include "set_play_time_dialog.h" #include "util/util.h" -#include "vk_device_info.h" #include "yuzu/game/game_list.h" #include "applets/qt_amiibo_settings.h" @@ -86,6 +86,7 @@ #include "qt_common/abstract/frontend.h" #include "qt_common/qt_common.h" +#include "qt_common/qt_string_lookup.h" #include "qt_common/util/content.h" #include "qt_common/util/fs.h" @@ -93,6 +94,8 @@ #include "qt_common/util/mod.h" #include "qt_common/util/path.h" +#include "qt_common/render/emu_thread.h" + // These are wrappers to avoid the calls to CreateDirectory and CreateFile because of the Windows // defines. static FileSys::VirtualDir VfsFilesystemCreateDirectoryWrapper(const std::string& path, @@ -315,73 +318,6 @@ enum class CalloutFlag : uint32_t { const int MainWindow::max_recent_files_item; -static void RemoveCachedContents() { - const auto cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir); - const auto offline_fonts = cache_dir / "fonts"; - const auto offline_manual = cache_dir / "offline_web_applet_manual"; - const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information"; - const auto offline_system_data = cache_dir / "offline_web_applet_system_data"; - - Common::FS::RemoveDirRecursively(offline_fonts); - Common::FS::RemoveDirRecursively(offline_manual); - Common::FS::RemoveDirRecursively(offline_legal_information); - Common::FS::RemoveDirRecursively(offline_system_data); -} - -static void LogRuntimes() { -#ifdef _MSC_VER - // It is possible that the name of the dll will change. - // vcruntime140.dll is for 2015 and onwards - static constexpr char runtime_dll_name[] = "vcruntime140.dll"; - UINT sz = GetFileVersionInfoSizeA(runtime_dll_name, nullptr); - bool runtime_version_inspection_worked = false; - if (sz > 0) { - std::vector buf(sz); - if (GetFileVersionInfoA(runtime_dll_name, 0, sz, buf.data())) { - VS_FIXEDFILEINFO* pvi; - sz = sizeof(VS_FIXEDFILEINFO); - if (VerQueryValueA(buf.data(), "\\", reinterpret_cast(&pvi), &sz)) { - if (pvi->dwSignature == VS_FFI_SIGNATURE) { - runtime_version_inspection_worked = true; - LOG_INFO(Frontend, "MSVC Compiler: {} Runtime: {}.{}.{}.{}", _MSC_VER, - pvi->dwProductVersionMS >> 16, pvi->dwProductVersionMS & 0xFFFF, - pvi->dwProductVersionLS >> 16, pvi->dwProductVersionLS & 0xFFFF); - } - } - } - } - if (!runtime_version_inspection_worked) { - LOG_INFO(Frontend, "Unable to inspect {}", runtime_dll_name); - } -#endif - LOG_INFO(Frontend, "Qt Compile: {} Runtime: {}", QT_VERSION_STR, qVersion()); -} - -static QString PrettyProductName() { -#ifdef _WIN32 - // After Windows 10 Version 2004, Microsoft decided to switch to a different notation: 20H2 - // With that notation change they changed the registry key used to denote the current version - QSettings windows_registry( - QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), - QSettings::NativeFormat); - const QString release_id = windows_registry.value(QStringLiteral("ReleaseId")).toString(); - if (release_id == QStringLiteral("2009")) { - const u32 current_build = windows_registry.value(QStringLiteral("CurrentBuild")).toUInt(); - const QString display_version = - windows_registry.value(QStringLiteral("DisplayVersion")).toString(); - const u32 ubr = windows_registry.value(QStringLiteral("UBR")).toUInt(); - u32 version = 10; - if (current_build >= 22000) { - version = 11; - } - return QStringLiteral("Windows %1 Version %2 (Build %3.%4)") - .arg(QString::number(version), display_version, QString::number(current_build), - QString::number(ubr)); - } -#endif - return QSysInfo::prettyProductName(); -} - namespace { constexpr std::array, 5> default_game_icon_sizes{ @@ -447,11 +383,6 @@ MainWindow::MainWindow(bool has_broken_vulkan) UISettings::RestoreWindowState(config); - QtCommon::system->Initialize(); - - Common::Log::Initialize(); - Common::Log::Start(); - LoadTranslation(); FrontendCommon::GenerateSettings(); @@ -472,10 +403,6 @@ MainWindow::MainWindow(bool has_broken_vulkan) play_time_manager = std::make_unique(); - Network::Init(); - - QtCommon::Meta::RegisterMetaTypes(); - InitializeWidgets(); InitializeDebugWidgets(); InitializeRecentFileMenuActions(); @@ -487,53 +414,9 @@ MainWindow::MainWindow(bool has_broken_vulkan) ConnectMenuEvents(); ConnectWidgetEvents(); - QtCommon::system->HIDCore().ReloadInputDevices(); + QtCommon::SetupHID(); controller_dialog->refreshConfiguration(); - const auto branch_name = std::string(Common::g_scm_branch); - const auto description = std::string(Common::g_scm_desc); - const auto build_id = std::string(Common::g_build_id); - - const auto yuzu_build = fmt::format("Eden Development Build | {}-{}", branch_name, description); - const auto override_build = - fmt::format(fmt::runtime(std::string(Common::g_title_bar_format_idle)), build_id); - const auto yuzu_build_version = override_build.empty() ? yuzu_build : override_build; - const auto processor_count = std::thread::hardware_concurrency(); - - LOG_INFO(Frontend, "Eden Version: {}", yuzu_build_version); - LogRuntimes(); -#ifdef ARCHITECTURE_x86_64 - const auto& caps = Common::GetCPUCaps(); - std::string cpu_string = caps.cpu_string; - if (caps.avx || caps.avx2 || caps.avx512f) { - cpu_string += " | AVX"; - if (caps.avx512f) { - cpu_string += "512"; - } else if (caps.avx2) { - cpu_string += '2'; - } - if (caps.fma || caps.fma4) { - cpu_string += " | FMA"; - } - } - LOG_INFO(Frontend, "Host CPU: {}", cpu_string); - if (std::optional processor_core = Common::GetProcessorCount()) { - LOG_INFO(Frontend, "Host CPU Cores: {}", *processor_core); - } -#endif - LOG_INFO(Frontend, "Host CPU Threads: {}", processor_count); - LOG_INFO(Frontend, "Host OS: {}", PrettyProductName().toStdString()); - LOG_INFO(Frontend, "Host RAM: {:.2f} GiB", - Common::GetMemInfo().TotalPhysicalMemory / f64{1_GiB}); - LOG_INFO(Frontend, "Host Swap: {:.2f} GiB", Common::GetMemInfo().TotalSwapMemory / f64{1_GiB}); -#ifdef _WIN32 - LOG_INFO(Frontend, "Host Timer Resolution: {:.4f} ms", - std::chrono::duration_cast>( - Common::Windows::SetCurrentTimerResolutionToMaximum()) - .count()); - QtCommon::system->CoreTiming().SetTimerResolutionNs( - Common::Windows::GetCurrentTimerResolution()); -#endif UpdateWindowTitle(); show(); @@ -548,13 +431,8 @@ MainWindow::MainWindow(bool has_broken_vulkan) } #endif - QtCommon::system->SetContentProvider(std::make_unique()); - QtCommon::system->RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual, - QtCommon::provider.get()); - QtCommon::system->GetFileSystemController().CreateFactories(*QtCommon::vfs); - - // Remove cached contents generated during the previous session - RemoveCachedContents(); + // Setup content providers. + QtCommon::SetupContentProviders(); // Gen keys if necessary OnCheckFirmwareDecryption(); @@ -1079,7 +957,7 @@ void MainWindow::InitializeWidgets() { #ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING ui->action_Report_Compatibility->setVisible(true); #endif - render_window = new GRenderWindow(this, emu_thread.get(), input_subsystem, *QtCommon::system); + render_window = new GRenderWindow(this, input_subsystem); render_window->hide(); game_list = new GameList(QtCommon::vfs, QtCommon::provider.get(), *play_time_manager, @@ -1539,11 +1417,12 @@ void MainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) { return; } if (UISettings::values.pause_when_in_background) { - if (emu_thread->IsRunning() && + if (QtCommon::emu_thread->IsRunning() && (state & (Qt::ApplicationHidden | Qt::ApplicationInactive))) { auto_paused = true; OnPauseGame(); - } else if (!emu_thread->IsRunning() && auto_paused && (state & Qt::ApplicationActive)) { + } else if (!QtCommon::emu_thread->IsRunning() && auto_paused && + (state & Qt::ApplicationActive)) { auto_paused = false; OnStartGame(); } @@ -1595,11 +1474,6 @@ void MainWindow::ConnectWidgetEvents() { connect(this, &MainWindow::UpdateInstallProgress, this, &MainWindow::IncrementInstallProgress); - connect(this, &MainWindow::EmulationStarting, render_window, - &GRenderWindow::OnEmulationStarting); - connect(this, &MainWindow::EmulationStopping, render_window, - &GRenderWindow::OnEmulationStopping); - // Software Keyboard Applet connect(this, &MainWindow::EmulationStarting, this, &MainWindow::SoftwareKeyboardExit); connect(this, &MainWindow::EmulationStopping, this, &MainWindow::SoftwareKeyboardExit); @@ -1753,7 +1627,7 @@ void MainWindow::ConnectMenuEvents() { } void MainWindow::UpdateMenuState() { - const bool is_paused = emu_thread == nullptr || !emu_thread->IsRunning(); + const bool is_paused = QtCommon::emu_thread == nullptr || !QtCommon::emu_thread->IsRunning(); const bool is_firmware_available = CheckFirmwarePresence(); const std::array running_actions{ @@ -1821,17 +1695,16 @@ void MainWindow::SetupPrepareForSleep() { } void MainWindow::OnPrepareForSleep(bool prepare_sleep) { - if (emu_thread == nullptr) { + if (QtCommon::emu_thread == nullptr) return; - } if (prepare_sleep) { - if (emu_thread->IsRunning()) { + if (QtCommon::emu_thread->IsRunning()) { auto_paused = true; OnPauseGame(); } } else { - if (!emu_thread->IsRunning() && auto_paused) { + if (!QtCommon::emu_thread->IsRunning() && auto_paused) { auto_paused = false; OnStartGame(); } @@ -1904,19 +1777,16 @@ void MainWindow::AllowOSSleep() { bool MainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletParameters params) { // Shutdown previous session if the emu thread is still active... - if (emu_thread != nullptr) { + if (QtCommon::emu_thread != nullptr) ShutdownGame(); - } - if (!render_window->InitRenderTarget()) { + if (!render_window->InitRenderTarget()) return false; - } QtCommon::system->SetFilesystem(QtCommon::vfs); - if (params.launch_type == Service::AM::LaunchType::FrontendInitiated) { + if (params.launch_type == Service::AM::LaunchType::FrontendInitiated) QtCommon::system->GetUserChannel().clear(); - } QtCommon::system->SetFrontendAppletSet({ std::make_unique(*this), // Amiibo Settings @@ -2023,36 +1893,6 @@ bool MainWindow::SelectAndSetCurrentUser( return true; } -void MainWindow::ConfigureFilesystemProvider(const std::string& filepath) { - // Ensure all NCAs are registered before launching the game - const auto file = QtCommon::vfs->OpenFile(filepath, FileSys::OpenMode::Read); - if (!file) { - return; - } - - if (QtCommon::provider->AddEntriesFromContainer(file)) { - return; - } - - auto loader = Loader::GetLoader(*QtCommon::system, file); - if (!loader) { - return; - } - - const auto file_type = loader->GetFileType(); - if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) { - return; - } - - u64 program_id = 0; - const auto res2 = loader->ReadProgramId(program_id); - if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) { - QtCommon::provider->AddEntry(FileSys::TitleType::Application, - FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()), - program_id, file); - } -} - void MainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletParameters params, StartGameType type) { LOG_INFO(Frontend, "Eden starting..."); @@ -2071,7 +1911,7 @@ void MainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletPa last_filename_booted = filename; - ConfigureFilesystemProvider(filename.toStdString()); + QtCommon::Content::configureFilesystemProvider(filename.toStdString()); const auto v_file = Core::GetGameFileFromPath(QtCommon::vfs, filename.toUtf8().constData()); const auto loader = Loader::GetLoader(*QtCommon::system, v_file, params.program_id, params.program_index); @@ -2116,23 +1956,23 @@ void MainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletPa game_list->setDisabled(true); // Create and start the emulation thread - emu_thread = std::make_unique(*QtCommon::system); - emit EmulationStarting(emu_thread.get()); - emu_thread->start(); + QtCommon::emu_thread = std::make_unique(); + emit EmulationStarting(); + QtCommon::emu_thread->start(); // Register an ExecuteProgram callback such that Core can execute a sub-program QtCommon::system->RegisterExecuteProgramCallback( [this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); }); QtCommon::system->RegisterExitCallback([this] { - emu_thread->ForceStop(); + QtCommon::emu_thread->ForceStop(); render_window->Exit(); }); connect(render_window, &GRenderWindow::Closed, this, &MainWindow::OnStopGame); connect(render_window, &GRenderWindow::MouseActivity, this, &MainWindow::OnMouseActivity); - connect(emu_thread.get(), &EmuThread::LoadProgress, loading_screen, + connect(QtCommon::emu_thread.get(), &EmuThread::LoadProgress, loading_screen, &LoadingScreen::OnLoadProgress, Qt::QueuedConnection); // Update the GUI @@ -2227,9 +2067,10 @@ bool MainWindow::OnShutdownBegin() { discord_rpc->Pause(); RequestGameExit(); - emu_thread->disconnect(); - emu_thread->SetRunning(true); + QtCommon::emu_thread->disconnect(); + QtCommon::emu_thread->SetRunning(true); + connect(QtCommon::emu_thread.get(), &QThread::finished, this, &MainWindow::OnEmulationStopped); emit EmulationStopping(); int shutdown_time = 1000; @@ -2243,7 +2084,6 @@ bool MainWindow::OnShutdownBegin() { shutdown_timer.setSingleShot(true); shutdown_timer.start(shutdown_time); connect(&shutdown_timer, &QTimer::timeout, this, &MainWindow::OnEmulationStopTimeExpired); - connect(emu_thread.get(), &QThread::finished, this, &MainWindow::OnEmulationStopped); // Disable everything to prevent anything from being triggered here ui->action_Pause->setEnabled(false); @@ -2261,17 +2101,17 @@ void MainWindow::OnShutdownBeginDialog() { } void MainWindow::OnEmulationStopTimeExpired() { - if (emu_thread) { - emu_thread->ForceStop(); + if (QtCommon::emu_thread) { + QtCommon::emu_thread->ForceStop(); } } void MainWindow::OnEmulationStopped() { shutdown_timer.stop(); - if (emu_thread) { - emu_thread->disconnect(); - emu_thread->wait(); - emu_thread.reset(); + if (QtCommon::emu_thread) { + QtCommon::emu_thread->disconnect(); + QtCommon::emu_thread->wait(); + QtCommon::emu_thread.reset(); } if (shutdown_dialog) { @@ -2912,7 +2752,7 @@ void MainWindow::OnMenuLoadFile() { is_load_file_select_active = true; const QString extensions = QStringLiteral("*.") - .append(GameList::supported_file_extensions.join(QStringLiteral(" *."))) + .append(QtCommon::supported_file_extensions.join(QStringLiteral(" *."))) .append(QStringLiteral(" main")); const QString file_filter = tr("Switch Executable (%1);;All Files (*.*)", "%1 is an identifier for the Switch executable file extensions.") @@ -3148,7 +2988,7 @@ void MainWindow::OnMenuRecentFile() { void MainWindow::OnStartGame() { PreventOSSleep(); - emu_thread->SetRunning(true); + QtCommon::emu_thread->SetRunning(true); UpdateMenuState(); OnTasStateChanged(); @@ -3174,7 +3014,7 @@ void MainWindow::OnRestartGame() { } void MainWindow::OnPauseGame() { - emu_thread->SetRunning(false); + QtCommon::emu_thread->SetRunning(false); play_time_manager->Stop(); UpdateMenuState(); AllowOSSleep(); @@ -3183,7 +3023,7 @@ void MainWindow::OnPauseGame() { void MainWindow::OnPauseContinueGame() { if (emulation_running) { - if (emu_thread->IsRunning()) { + if (QtCommon::emu_thread->IsRunning()) { OnPauseGame(); } else { OnStartGame(); @@ -3863,12 +3703,9 @@ void MainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_ } void MainWindow::OnLoadAmiibo() { - if (emu_thread == nullptr || !emu_thread->IsRunning()) { + if (QtCommon::emu_thread == nullptr || !QtCommon::emu_thread->IsRunning() || + is_amiibo_file_select_active) return; - } - if (is_amiibo_file_select_active) { - return; - } auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo(); @@ -3972,79 +3809,21 @@ void MainWindow::OnVerifyInstalledContents() { QtCommon::Content::VerifyInstalledContents(); } -void MainWindow::InstallFirmware(const QString& location, bool recursive) { - QtCommon::Content::InstallFirmware(location, recursive); +void MainWindow::OnInstallFirmware() { + QtCommon::Content::InstallFirmware(); OnCheckFirmwareDecryption(); } -void MainWindow::OnInstallFirmware() { - // Don't do this while emulation is running, that'd probably be a bad idea. - if (emu_thread != nullptr && emu_thread->IsRunning()) { - return; - } - - // Check for installed keys, error out, suggest restart? - if (!ContentManager::AreKeysPresent()) { - QMessageBox::information( - this, tr("Keys not installed"), - tr("Install decryption keys and restart Eden before attempting to install firmware.")); - return; - } - - const QString firmware_source_location = QFileDialog::getExistingDirectory( - this, tr("Select Dumped Firmware Source Location"), {}, QFileDialog::ShowDirsOnly); - if (firmware_source_location.isEmpty()) { - return; - } - - InstallFirmware(firmware_source_location); -} - void MainWindow::OnInstallFirmwareFromZIP() { - // Don't do this while emulation is running, that'd probably be a bad idea. - if (emu_thread != nullptr && emu_thread->IsRunning()) { - return; - } - - // Check for installed keys, error out, suggest restart? - if (!ContentManager::AreKeysPresent()) { - QMessageBox::information( - this, tr("Keys not installed"), - tr("Install decryption keys and restart Eden before attempting to install firmware.")); - return; - } - - const QString firmware_zip_location = QFileDialog::getOpenFileName( - this, tr("Select Dumped Firmware ZIP"), {}, tr("Zipped Archives (*.zip)")); - if (firmware_zip_location.isEmpty()) { - return; - } - - const QString qCacheDir = QtCommon::Content::UnzipFirmwareToTmp(firmware_zip_location); - - // In this case, it has to be done recursively, since sometimes people - // will pack it into a subdirectory after dumping - if (!qCacheDir.isEmpty()) { - InstallFirmware(qCacheDir, true); - std::error_code ec; - std::filesystem::remove_all(std::filesystem::temp_directory_path() / "eden" / "firmware", - ec); - - if (ec) { - QMessageBox::warning(this, tr("Firmware cleanup failed"), - tr("Failed to clean up extracted firmware cache.\n" - "Check write permissions in the system temp directory and try " - "again.\nOS reported error: %1") - .arg(QString::fromStdString(ec.message()))); - } - } + QtCommon::Content::InstallFirmwareZip(); + OnCheckFirmwareDecryption(); } +// TODO(crueter): QtCommon this: game list populate can be a signal? void MainWindow::OnInstallDecryptionKeys() { // Don't do this while emulation is running. - if (emu_thread != nullptr && emu_thread->IsRunning()) { + if (QtCommon::emu_thread != nullptr && QtCommon::emu_thread->IsRunning()) return; - } QtCommon::Content::InstallKeys(); @@ -4072,11 +3851,10 @@ void MainWindow::OnDataDialog() { void MainWindow::OnToggleFilterBar() { game_list->SetFilterVisible(ui->action_Show_Filter_Bar->isChecked()); - if (ui->action_Show_Filter_Bar->isChecked()) { + if (ui->action_Show_Filter_Bar->isChecked()) game_list->SetFilterFocus(); - } else { + else game_list->ClearFilter(); - } } void MainWindow::OnToggleStatusBar() { @@ -4084,9 +3862,8 @@ void MainWindow::OnToggleStatusBar() { } void MainWindow::OnTogglePerfOverlay() { - if (perf_overlay) { + if (perf_overlay) perf_overlay->setVisible(ui->action_Show_Performance_Overlay->isChecked()); - } } void MainWindow::OnGameListRefresh() { @@ -4191,9 +3968,8 @@ void MainWindow::OnCreateHomeMenuApplicationMenuShortcut() { } void MainWindow::OnCaptureScreenshot() { - if (emu_thread == nullptr || !emu_thread->IsRunning()) { + if (QtCommon::emu_thread == nullptr || !QtCommon::emu_thread->IsRunning()) return; - } const u64 title_id = QtCommon::system->GetApplicationProcessProgramID(); const auto screenshot_path = @@ -4205,9 +3981,8 @@ void MainWindow::OnCaptureScreenshot() { .arg(title_id, 16, 16, QLatin1Char{'0'}) .arg(date); - if (!Common::FS::CreateDir(screenshot_path.toStdString())) { + if (!Common::FS::CreateDir(screenshot_path.toStdString())) return; - } #ifdef _WIN32 if (UISettings::values.enable_screenshot_save_as) { @@ -4313,16 +4088,15 @@ void MainWindow::OnTasStateChanged() { } void MainWindow::UpdateStatusBar() { - if (emu_thread == nullptr || !QtCommon::system->IsPoweredOn()) { + if (QtCommon::emu_thread == nullptr || !QtCommon::system->IsPoweredOn()) { status_bar_update_timer.stop(); return; } - if (Settings::values.tas_enable) { + if (Settings::values.tas_enable) tas_label->setText(GetTasStateDescription()); - } else { + else tas_label->clear(); - } auto results = QtCommon::system->GetAndResetPerfStats(); auto& shader_notify = QtCommon::system->GPU().ShaderNotify(); @@ -4444,14 +4218,13 @@ void MainWindow::UpdateUISettings() { } void MainWindow::UpdateInputDrivers() { - if (!input_subsystem) { + if (!input_subsystem) return; - } input_subsystem->PumpEvents(); } void MainWindow::HideMouseCursor() { - if (emu_thread == nullptr && UISettings::values.hide_mouse) { + if (QtCommon::emu_thread == nullptr && UISettings::values.hide_mouse) { mouse_hide_timer.stop(); ShowMouseCursor(); return; @@ -4461,9 +4234,8 @@ void MainWindow::HideMouseCursor() { void MainWindow::ShowMouseCursor() { render_window->unsetCursor(); - if (emu_thread != nullptr && UISettings::values.hide_mouse) { + if (QtCommon::emu_thread != nullptr && UISettings::values.hide_mouse) mouse_hide_timer.start(); - } } void MainWindow::OnMouseActivity() { @@ -4643,14 +4415,14 @@ bool MainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed } bool MainWindow::ConfirmClose() { - if (emu_thread == nullptr || - UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Never) { + if (QtCommon::emu_thread == nullptr || + UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Never) return true; - } + if (!QtCommon::system->GetExitLocked() && - UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game) { + UISettings::values.confirm_before_stopping.GetValue() == ConfirmStop::Ask_Based_On_Game) return true; - } + const auto text = tr("Are you sure you want to close Eden?"); return question(this, tr("Eden"), text); } @@ -4671,9 +4443,8 @@ void MainWindow::closeEvent(QCloseEvent* event) { game_list->UnloadController(); // Shutdown session if the emu thread is active... - if (emu_thread != nullptr) { + if (QtCommon::emu_thread != nullptr) ShutdownGame(); - } render_window->close(); multiplayer_state->Close(); @@ -4736,7 +4507,7 @@ void MainWindow::dragMoveEvent(QDragMoveEvent* event) { } bool MainWindow::ConfirmChangeGame() { - if (emu_thread == nullptr) + if (QtCommon::emu_thread == nullptr) return true; // Use custom question to link controller navigation @@ -4747,9 +4518,9 @@ bool MainWindow::ConfirmChangeGame() { } bool MainWindow::ConfirmForceLockedExit() { - if (emu_thread == nullptr) { + if (QtCommon::emu_thread == nullptr) return true; - } + const auto text = tr("The currently running application has requested Eden to not exit.\n\n" "Would you like to bypass this and exit anyway?"); @@ -4757,9 +4528,8 @@ bool MainWindow::ConfirmForceLockedExit() { } void MainWindow::RequestGameExit() { - if (!QtCommon::system->IsPoweredOn()) { + if (!QtCommon::system->IsPoweredOn()) return; - } QtCommon::system->SetExitRequested(true); QtCommon::system->GetAppletManager().RequestExit(); @@ -4772,14 +4542,14 @@ void MainWindow::filterBarSetChecked(bool state) { static void AdjustLinkColor() { QPalette new_pal(qApp->palette()); - if (UISettings::IsDarkTheme()) { + + if (UISettings::IsDarkTheme()) new_pal.setColor(QPalette::Link, QColor(0, 190, 255, 255)); - } else { + else new_pal.setColor(QPalette::Link, QColor(0, 140, 200, 255)); - } - if (qApp->palette().color(QPalette::Link) != new_pal.color(QPalette::Link)) { + + if (qApp->palette().color(QPalette::Link) != new_pal.color(QPalette::Link)) qApp->setPalette(new_pal); - } } void MainWindow::UpdateUITheme() { @@ -4787,9 +4557,8 @@ void MainWindow::UpdateUITheme() { UISettings::themes[static_cast(UISettings::default_theme)].second); QString current_theme = QString::fromStdString(UISettings::values.theme); - if (current_theme.isEmpty()) { + if (current_theme.isEmpty()) current_theme = default_theme; - } #ifdef _WIN32 QIcon::setThemeName(current_theme); @@ -4850,17 +4619,15 @@ void MainWindow::LoadTranslation() { QStringLiteral(":/languages/")); } - if (loaded) { + if (loaded) qApp->installTranslator(&translator); - } else { + else UISettings::values.language = std::string("en"); - } } void MainWindow::OnLanguageChanged(const QString& locale) { - if (UISettings::values.language.GetValue() != std::string("en")) { + if (UISettings::values.language.GetValue() != std::string("en")) qApp->removeTranslator(&translator); - } QList actions = game_size_actions->actions(); for (size_t i = 0; i < default_game_icon_sizes.size(); i++) { @@ -4876,11 +4643,10 @@ void MainWindow::OnLanguageChanged(const QString& locale) { void MainWindow::SetDiscordEnabled([[maybe_unused]] bool state) { #ifdef USE_DISCORD_PRESENCE - if (state) { + if (state) discord_rpc = std::make_unique(*QtCommon::system); - } else { + else discord_rpc = std::make_unique(); - } #else discord_rpc = std::make_unique(); #endif diff --git a/src/yuzu/main_window.h b/src/yuzu/main_window.h index b676c0534a..65da01e9ca 100644 --- a/src/yuzu/main_window.h +++ b/src/yuzu/main_window.h @@ -20,9 +20,9 @@ #include "common/common_types.h" #include "common/settings_enums.h" #include "frontend_common/content_manager.h" -#include "frontend_common/update_checker.h" #include "input_common/drivers/tas_input.h" #include "qt_common/config/qt_config.h" +#include "qt_common/qt_common.h" #include "qt_common/util/game.h" #include "yuzu/compatibility_list.h" #include "yuzu/hotkeys.h" @@ -38,6 +38,7 @@ #ifdef ENABLE_UPDATE_CHECKER #include #include +#include "common/net/net.h" #endif class QtConfig; @@ -66,11 +67,6 @@ class QtProfileSelectionDialog; class QtSoftwareKeyboardDialog; class QtNXWebEngineView; -enum class StartGameType { - Normal, // Can use custom configuration - Global, // Only uses global configuration -}; - namespace VideoCore { class ShaderNotify; } @@ -184,11 +180,8 @@ signals: * Signal that is emitted when a new EmuThread has been created and an emulation session is * about to start. At this time, the core system emulation has been initialized, and all * emulation handles and memory should be valid. - * - * @param emu_thread Pointer to the newly created EmuThread (to be used by widgets that need to - * access/change emulation state). */ - void EmulationStarting(EmuThread* emu_thread); + void EmulationStarting(); /** * Signal that is emitted when emulation is about to stop. At this time, the EmuThread and core @@ -465,7 +458,6 @@ private: bool CheckFirmwarePresence(); void SetFirmwareVersion(); void SetFPSSuffix(); - void ConfigureFilesystemProvider(const std::string& filepath); /** * Open (or not) the right confirm dialog based on current setting and game exit lock * @returns true if the player confirmed or the settings do no require it @@ -538,7 +530,6 @@ private: // Whether emulation is currently running in yuzu. bool emulation_running = false; - std::unique_ptr emu_thread; // The path to the game currently running QString current_game_path; // Whether a user was set on the command line (skips UserSelector if it's forced to show up) @@ -599,8 +590,6 @@ private: const std::string& game_title, QtCommon::Game::ShortcutTarget target, std::string arguments, const bool needs_title); - void InstallFirmware(const QString& location, bool recursive = false); - protected: void dropEvent(QDropEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override; diff --git a/src/yuzu/updater/update_dialog.h b/src/yuzu/updater/update_dialog.h index 692481b710..e821ef660d 100644 --- a/src/yuzu/updater/update_dialog.h +++ b/src/yuzu/updater/update_dialog.h @@ -15,7 +15,7 @@ class UpdateDialog : public QDialog { Q_OBJECT public: - explicit UpdateDialog(const Common::Net::Release &release, QWidget* parent = nullptr); + explicit UpdateDialog(const Common::Net::Release& release, QWidget* parent = nullptr); ~UpdateDialog(); private slots: @@ -23,6 +23,6 @@ private slots: private: Ui::UpdateDialog* ui; - QList m_buttons; + QList m_buttons; Common::Net::Asset m_asset; }; diff --git a/src/yuzu/util/util.cpp b/src/yuzu/util/util.cpp index a3933d9b63..e37d9d03e4 100644 --- a/src/yuzu/util/util.cpp +++ b/src/yuzu/util/util.cpp @@ -43,111 +43,6 @@ QPixmap CreateCirclePixmapFromColor(const QColor& color) { return circle_pixmap; } -bool SaveIconToFile(const std::filesystem::path& icon_path, const QImage& image) { -#if defined(WIN32) -#pragma pack(push, 2) - struct IconDir { - WORD id_reserved; - WORD id_type; - WORD id_count; - }; - - struct IconDirEntry { - BYTE width; - BYTE height; - BYTE color_count; - BYTE reserved; - WORD planes; - WORD bit_count; - DWORD bytes_in_res; - DWORD image_offset; - }; -#pragma pack(pop) - - const QImage source_image = image.convertToFormat(QImage::Format_RGB32); - constexpr std::array scale_sizes{256, 128, 64, 48, 32, 24, 16}; - constexpr int bytes_per_pixel = 4; - - const IconDir icon_dir{ - .id_reserved = 0, - .id_type = 1, - .id_count = static_cast(scale_sizes.size()), - }; - - Common::FS::IOFile icon_file(icon_path.string(), Common::FS::FileAccessMode::Write, - Common::FS::FileType::BinaryFile); - if (!icon_file.IsOpen()) { - return false; - } - - if (!icon_file.Write(icon_dir)) { - return false; - } - - std::size_t image_offset = sizeof(IconDir) + (sizeof(IconDirEntry) * scale_sizes.size()); - for (std::size_t i = 0; i < scale_sizes.size(); i++) { - const int image_size = scale_sizes[i] * scale_sizes[i] * bytes_per_pixel; - const IconDirEntry icon_entry{ - .width = static_cast(scale_sizes[i]), - .height = static_cast(scale_sizes[i]), - .color_count = 0, - .reserved = 0, - .planes = 1, - .bit_count = bytes_per_pixel * 8, - .bytes_in_res = static_cast(sizeof(BITMAPINFOHEADER) + image_size), - .image_offset = static_cast(image_offset), - }; - image_offset += icon_entry.bytes_in_res; - if (!icon_file.Write(icon_entry)) { - return false; - } - } - - for (std::size_t i = 0; i < scale_sizes.size(); i++) { - const QImage scaled_image = source_image.scaled( - scale_sizes[i], scale_sizes[i], Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - const BITMAPINFOHEADER info_header{ - .biSize = sizeof(BITMAPINFOHEADER), - .biWidth = scaled_image.width(), - .biHeight = scaled_image.height() * 2, - .biPlanes = 1, - .biBitCount = bytes_per_pixel * 8, - .biCompression = BI_RGB, - .biSizeImage{}, - .biXPelsPerMeter{}, - .biYPelsPerMeter{}, - .biClrUsed{}, - .biClrImportant{}, - }; - - if (!icon_file.Write(info_header)) { - return false; - } - - for (int y = 0; y < scaled_image.height(); y++) { - const auto* line = scaled_image.scanLine(scaled_image.height() - 1 - y); - std::vector line_data(scaled_image.width() * bytes_per_pixel); - std::memcpy(line_data.data(), line, line_data.size()); - if (!icon_file.Write(line_data)) { - return false; - } - } - } - icon_file.Close(); - - return true; -#elif defined(__unix__) && !defined(__APPLE__) && !defined(__ANDROID__) - // Convert and write the icon as a PNG - if (!image.save(QString::fromStdString(icon_path.string()))) { - LOG_ERROR(Frontend, "Could not write icon as PNG to file"); - } else { - LOG_INFO(Frontend, "Wrote an icon to {}", icon_path.string()); - } - return true; -#else - return false; -#endif -} const std::optional GetProfileID() { // if there's only a single profile, the user probably wants to use that... right? const auto& profiles = QtCommon::system->GetProfileManager().FindExistingProfileUUIDs(); diff --git a/src/yuzu/util/util.h b/src/yuzu/util/util.h index 7b482aa11d..9920aa9c78 100644 --- a/src/yuzu/util/util.h +++ b/src/yuzu/util/util.h @@ -6,7 +6,6 @@ #pragma once -#include #include #include #include "common/uuid.h" @@ -24,14 +23,6 @@ */ [[nodiscard]] QPixmap CreateCirclePixmapFromColor(const QColor& color); -/** - * Saves a windows icon to a file - * @param path The icons path - * @param image The image to save - * @return bool If the operation succeeded - */ -[[nodiscard]] bool SaveIconToFile(const std::filesystem::path& icon_path, const QImage& image); - /** * Prompt the user for a profile ID. If there is only one valid profile, returns that profile. * @return The selected profile, or an std::nullopt if none were selected diff --git a/src/yuzu/vk_device_info.h b/src/yuzu/vk_device_info.h deleted file mode 100644 index bda8262f4e..0000000000 --- a/src/yuzu/vk_device_info.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include -#include -#include -#include -#include "common/common_types.h" -#include "vulkan/vulkan_core.h" - -class QWindow; - -namespace Settings { -enum class VSyncMode : u32; -} -// #include "common/settings.h" - -namespace VkDeviceInfo { -// Short class to record Vulkan driver information for configuration purposes -class Record { -public: - explicit Record(std::string_view name, const std::vector& vsync_modes, - bool has_broken_compute); - ~Record(); - - const std::string name; - const std::vector vsync_support; - const bool has_broken_compute; -}; - -void PopulateRecords(std::vector& records, QWindow* window); -} // namespace VkDeviceInfo From 30186c6cd83258e5c611918f64d43fb5d014b81e Mon Sep 17 00:00:00 2001 From: crueter Date: Fri, 1 May 2026 15:23:09 -0400 Subject: [PATCH 56/58] Fix license headers --- src/qt_common/util/vk.h | 3 +++ src/yuzu/configuration/configure_graphics.h | 2 +- src/yuzu/util/util.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/qt_common/util/vk.h b/src/qt_common/util/vk.h index 73f2b6ef82..3e6730f643 100644 --- a/src/qt_common/util/vk.h +++ b/src/qt_common/util/vk.h @@ -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 diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index 9241a8d6df..9002af437b 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h @@ -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: 2016 Citra Emulator Project diff --git a/src/yuzu/util/util.h b/src/yuzu/util/util.h index 9920aa9c78..9c3d5aa84a 100644 --- a/src/yuzu/util/util.h +++ b/src/yuzu/util/util.h @@ -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: 2015 Citra Emulator Project From 1075e1ef9bc37bc98c6aba74036f3357a259f92c Mon Sep 17 00:00:00 2001 From: crueter Date: Fri, 1 May 2026 15:37:30 -0400 Subject: [PATCH 57/58] Fix build? Signed-off-by: crueter --- src/dedicated_room/CMakeLists.txt | 2 +- src/qt_common/CMakeLists.txt | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/dedicated_room/CMakeLists.txt b/src/dedicated_room/CMakeLists.txt index ff9e458056..8ca138473f 100644 --- a/src/dedicated_room/CMakeLists.txt +++ b/src/dedicated_room/CMakeLists.txt @@ -9,7 +9,7 @@ add_library(yuzu-room STATIC EXCLUDE_FROM_ALL yuzu_room.h yuzu_room.rc) -target_link_libraries(yuzu-room PRIVATE common) +target_link_libraries(yuzu-room PRIVATE common network) if (ENABLE_WEB_SERVICE) target_compile_definitions(yuzu-room PRIVATE ENABLE_WEB_SERVICE) target_link_libraries(yuzu-room PRIVATE web_service) diff --git a/src/qt_common/CMakeLists.txt b/src/qt_common/CMakeLists.txt index 8764160af1..a8c4e51240 100644 --- a/src/qt_common/CMakeLists.txt +++ b/src/qt_common/CMakeLists.txt @@ -59,9 +59,7 @@ if (USE_DISCORD_PRESENCE) endif() # TODO(crueter) -if (ENABLE_QT) - target_link_libraries(qt_common PRIVATE Qt6::Widgets) -endif() +target_link_libraries(qt_common PRIVATE Qt6::Widgets) target_compile_definitions(qt_common PUBLIC # Use QStringBuilder for string concatenation to reduce @@ -83,7 +81,7 @@ target_compile_definitions(qt_common PUBLIC ) target_link_libraries(qt_common PRIVATE core Qt6::Core Qt6::Concurrent SimpleIni::SimpleIni QuaZip::QuaZip) -target_link_libraries(qt_common PUBLIC frozen::frozen-headers) +target_link_libraries(qt_common PUBLIC frozen::frozen-headers Vulkan::Headers) target_link_libraries(qt_common PRIVATE gamemode::headers frontend_common) if (ENABLE_OPENGL) From 1d3c8cde3149958744bf9b6700a1c221f7a7ed6b Mon Sep 17 00:00:00 2001 From: crueter Date: Sat, 2 May 2026 14:51:27 -0400 Subject: [PATCH 58/58] Fix windows Signed-off-by: crueter --- src/qt_common/util/game.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt_common/util/game.cpp b/src/qt_common/util/game.cpp index 33ff32bf37..ddbe979765 100644 --- a/src/qt_common/util/game.cpp +++ b/src/qt_common/util/game.cpp @@ -21,6 +21,7 @@ #include #include "common/scope_exit.h" #include "common/string_util.h" +#include "common/fs/file.h" #else #include #include "fmt/ostream.h"