Compare commits

..

3 Commits

Author SHA1 Message Date
lizzie cf1d905786 2026-09-15 07:28:16
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-15 07:28:17 +00:00
lizzie 60003ea642 2026-09-15 06:40:57
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-15 06:40:58 +00:00
lizzie 43607d0b7e 2026-09-15 06:36:27
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-15 06:36:27 +00:00
14 changed files with 48 additions and 62 deletions
+2 -2
View File
@@ -208,9 +208,9 @@ UUID UUID::MakeRandomRFC4122V4() {
return uuid; return uuid;
} }
UUID UUID::MakeRFC4122V5(std::span<u8, 16> sha1) { UUID UUID::MakeRFC4122V5(std::span<u8, 20> sha1) {
UUID uuid{}; UUID uuid{};
std::memcpy(&uuid.uuid, sha1.data(), sha1.size()); std::memcpy(&uuid.uuid, sha1.data(), sizeof(UUID));
uuid.uuid[8] = 0x80 | (uuid.uuid[8] & 0x3F); uuid.uuid[8] = 0x80 | (uuid.uuid[8] & 0x3F);
uuid.uuid[6] = 0x50 | (uuid.uuid[6] & 0xF); uuid.uuid[6] = 0x50 | (uuid.uuid[6] & 0xF);
return uuid; return uuid;
+1 -1
View File
@@ -104,7 +104,7 @@ struct UUID {
/// @returns A random UUID that is RFC 4122 Version 4 compliant. /// @returns A random UUID that is RFC 4122 Version 4 compliant.
[[nodiscard]] static UUID MakeRandomRFC4122V4(); [[nodiscard]] static UUID MakeRandomRFC4122V4();
[[nodiscard]] static UUID MakeRFC4122V5(std::span<u8, 16> sha1); [[nodiscard]] static UUID MakeRFC4122V5(std::span<u8, 20> sha1);
friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default; friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default;
}; };
+2 -2
View File
@@ -796,8 +796,6 @@ add_library(core STATIC
hle/service/ns/application_manager_interface.h hle/service/ns/application_manager_interface.h
hle/service/ns/application_version_interface.cpp hle/service/ns/application_version_interface.cpp
hle/service/ns/application_version_interface.h hle/service/ns/application_version_interface.h
hle/service/ns/async_result.cpp
hle/service/ns/async_result.h
hle/service/ns/content_management_interface.cpp hle/service/ns/content_management_interface.cpp
hle/service/ns/content_management_interface.h hle/service/ns/content_management_interface.h
hle/service/ns/develop_interface.cpp hle/service/ns/develop_interface.cpp
@@ -812,6 +810,8 @@ add_library(core STATIC
hle/service/ns/ecommerce_interface.h hle/service/ns/ecommerce_interface.h
hle/service/ns/factory_reset_interface.cpp hle/service/ns/factory_reset_interface.cpp
hle/service/ns/factory_reset_interface.h hle/service/ns/factory_reset_interface.h
hle/service/ns/i_async_result.cpp
hle/service/ns/i_async_result.h
hle/service/ns/language.cpp hle/service/ns/language.cpp
hle/service/ns/language.h hle/service/ns/language.h
hle/service/ns/ns.cpp hle/service/ns/ns.cpp
+8 -25
View File
@@ -12,7 +12,6 @@
#include "hid_core/frontend/emulated_controller.h" #include "hid_core/frontend/emulated_controller.h"
#include "hid_core/hid_core.h" #include "hid_core/hid_core.h"
#include "hid_core/hid_types.h" #include "hid_core/hid_types.h"
#include <array>
namespace Core::Frontend { namespace Core::Frontend {
@@ -30,39 +29,23 @@ void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callbac
const std::size_t min_supported_players = const std::size_t min_supported_players =
parameters.enable_single_mode ? 1 : parameters.min_players; parameters.enable_single_mode ? 1 : parameters.min_players;
using Core::HID::NpadStyleIndex;
const std::size_t max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players;
std::size_t num_selected_players = 0;
std::array<bool, HID::HIDCore::available_controllers> keep_connected{};
// reserve existing AND valid players before filling slots. include Handheld, but not other // Disconnect Handheld first.
for (std::size_t index = 0; index < hid_core.available_controllers - 1; ++index) {
const auto* controller = hid_core.GetEmulatedControllerByIndex(index);
if (!parameters.keep_controllers_connected || !controller->IsConnected() || num_selected_players >= max_supported_players) continue;
const auto style = controller->GetNpadStyleIndex();
keep_connected[index] =
(style == NpadStyleIndex::Fullkey && parameters.allow_pro_controller) ||
(style == NpadStyleIndex::JoyconDual && parameters.allow_dual_joycons) ||
(style == NpadStyleIndex::JoyconLeft && parameters.allow_left_joycon) ||
(style == NpadStyleIndex::JoyconRight && parameters.allow_right_joycon) ||
(style == NpadStyleIndex::Handheld && parameters.enable_single_mode && parameters.allow_handheld && !Settings::IsDockedMode()) ||
(style == NpadStyleIndex::GameCube && parameters.allow_gamecube_controller);
num_selected_players += keep_connected[index];
}
auto* handheld = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); auto* handheld = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
if (!keep_connected[hid_core.available_controllers - 2]) handheld->Disconnect(); handheld->Disconnect();
// Deduce the best configuration based on the input parameters. // Deduce the best configuration based on the input parameters.
for (std::size_t index = 0; index < hid_core.available_controllers - 2; ++index) { for (std::size_t index = 0; index < hid_core.available_controllers - 2; ++index) {
auto* controller = hid_core.GetEmulatedControllerByIndex(index); auto* controller = hid_core.GetEmulatedControllerByIndex(index);
if (keep_connected[index]) continue; // First, disconnect all controllers regardless of the value of keep_controllers_connected.
// This makes it easy to connect the desired controllers.
controller->Disconnect(); controller->Disconnect();
// only add players still needed to reach the minimum // Only connect the minimum number of required players.
if (num_selected_players >= min_supported_players) continue; if (index >= min_supported_players) {
++num_selected_players; continue;
}
// Connect controllers based on the following priority list from highest to lowest priority: // Connect controllers based on the following priority list from highest to lowest priority:
// Pro Controller -> Dual Joycons -> Left Joycon/Right Joycon -> Handheld // Pro Controller -> Dual Joycons -> Left Joycon/Right Joycon -> Handheld
@@ -347,22 +347,21 @@ Result IApplicationFunctions::NotifyRunning(Out<bool> out_became_running) {
Result IApplicationFunctions::GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id) { Result IApplicationFunctions::GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id) {
LOG_WARNING(Service_AM, "(stubbed)"); LOG_WARNING(Service_AM, "(stubbed)");
R_UNLESS(out_pseudo_device_id != nullptr, ResultUnknown); R_UNLESS(out_pseudo_device_id, ResultUnknown);
// This should be hashed with the device specific hash // This should be hashed with the device specific hash
// for now this will do // for now this will do
const auto res = FileSys::PatchManager::GetMetadataFromBaseOrUpdate(system, m_applet->program_id); const auto res = FileSys::PatchManager::GetMetadataFromBaseOrUpdate(system, m_applet->program_id);
R_UNLESS(res.first != nullptr, ResultUnknown); u8 hash[EVP_MAX_MD_SIZE];
std::array<u8, EVP_MAX_MD_SIZE> hash;
unsigned int hash_len = 0; unsigned int hash_len = 0;
auto const seed = res.first->raw.seed_for_pseudo_device_id; auto const seed = res.first->raw.seed_for_pseudo_device_id;
EVP_MD_CTX *ctx = EVP_MD_CTX_new(); EVP_MD_CTX *ctx = EVP_MD_CTX_new();
auto const algorithm = EVP_sha1(); auto const algorithm = EVP_sha1();
EVP_DigestInit_ex(ctx, algorithm, nullptr); EVP_DigestInit_ex(ctx, algorithm, nullptr);
EVP_DigestUpdate(ctx, &seed, sizeof(seed)); EVP_DigestUpdate(ctx, &seed, sizeof(seed));
EVP_DigestFinal_ex(ctx, hash.data(), &hash_len); EVP_DigestFinal_ex(ctx, hash, &hash_len);
EVP_MD_CTX_free(ctx); EVP_MD_CTX_free(ctx);
*out_pseudo_device_id = Common::UUID::MakeRFC4122V5(std::span<u8, 16>{hash.begin(), hash.begin() + 16}); *out_pseudo_device_id = Common::UUID::MakeRFC4122V5(std::span<u8, 20>{hash, std::size(hash)});
R_SUCCEED(); R_SUCCEED();
} }
@@ -7,7 +7,7 @@
#pragma once #pragma once
#include "core/hle/service/cmif_types.h" #include "core/hle/service/cmif_types.h"
#include "core/hle/service/ns/async_result.h" #include "core/hle/service/ns/i_async_result.h"
#include "core/hle/service/ns/language.h" #include "core/hle/service/ns/language.h"
#include "core/hle/service/ns/ns_types.h" #include "core/hle/service/ns/ns_types.h"
#include "core/hle/service/os/event.h" #include "core/hle/service/os/event.h"
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/async_result.h" #include "core/hle/service/ns/i_async_result.h"
#include <cstring> #include <cstring>
@@ -311,30 +311,27 @@ void IReadOnlyApplicationControlDataInterface::ListApplicationIcon(HLERequestCon
// u64 - app count // u64 - app count
memory.WriteBlock(t_mem_address + out_length, &app_count, sizeof(u64)); memory.WriteBlock(t_mem_address + out_length, &app_count, sizeof(u64));
out_length += sizeof(u64); out_length += sizeof(u64);
ASSERT(out_length <= t_mem->GetSize());
// [list of u64] - size of icons // [list of u64] - size of icons
for (size_t i = 0; i < app_count; ++i) { for (size_t i = 0; i < app_count; ++i) {
const u64 app_id = app_ids_buffer[i]; const u64 app_id = app_ids_buffer[i];
const FileSys::PatchManager pm{app_id, system.GetFileSystemController(), system.GetContentProvider()}; const FileSys::PatchManager pm{app_id, system.GetFileSystemController(), system.GetContentProvider()};
if (const auto control = pm.GetControlMetadata(); control.second) { const auto control = pm.GetControlMetadata();
u64 full_size = control.second->GetSize(); u64 full_size = control.second->GetSize();
memory.WriteBlock(t_mem_address + out_length, &full_size, sizeof(u64)); memory.WriteBlock(t_mem_address + out_length, &full_size, sizeof(u64));
}
out_length += sizeof(u64); out_length += sizeof(u64);
ASSERT(out_length <= t_mem->GetSize());
} }
// [list of raw icon data] // [list of raw icon data]
std::vector<u8> full_icon_data;
for (size_t i = 0; i < app_count; ++i) { for (size_t i = 0; i < app_count; ++i) {
const u64 app_id = app_ids_buffer[i]; const u64 app_id = app_ids_buffer[i];
const FileSys::PatchManager pm{app_id, system.GetFileSystemController(), system.GetContentProvider()}; const FileSys::PatchManager pm{app_id, system.GetFileSystemController(), system.GetContentProvider()};
if (const auto control = pm.GetControlMetadata(); control.second) { const auto control = pm.GetControlMetadata();
if (auto const full_size = control.second->GetSize(); full_size > 0) { auto const full_size = control.second->GetSize();
std::vector<u8> full_icon_data(full_size); if (full_size > 0) {
control.second->Read(full_icon_data.data(), full_size, 0); full_icon_data.resize(full_size);
memory.WriteBlock(t_mem_address + out_length, full_icon_data.data(), full_size); control.second->Read(full_icon_data.data(), full_size, 0);
out_length += full_size; memory.WriteBlock(t_mem_address + out_length, full_icon_data.data(), full_size);
ASSERT(out_length <= t_mem->GetSize()); out_length += full_size;
}
} }
} }
} }
@@ -348,12 +345,6 @@ void IReadOnlyApplicationControlDataInterface::ListApplicationIcon(HLERequestCon
void IReadOnlyApplicationControlDataInterface::ListApplicationTitle(HLERequestContext& ctx) { void IReadOnlyApplicationControlDataInterface::ListApplicationTitle(HLERequestContext& ctx) {
const auto app_ids_buffer = ctx.ReadBuffer(); const auto app_ids_buffer = ctx.ReadBuffer();
const size_t app_count = app_ids_buffer.size() / sizeof(u64); const size_t app_count = app_ids_buffer.size() / sizeof(u64);
std::vector<u64> application_ids(app_count);
if (app_count > 0) {
std::memcpy(application_ids.data(), app_ids_buffer.data(), app_count * sizeof(u64));
}
auto t_mem_obj = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(ctx.GetCopyHandle(0)); auto t_mem_obj = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(ctx.GetCopyHandle(0));
auto* t_mem = t_mem_obj.GetPointerUnsafe(); auto* t_mem = t_mem_obj.GetPointerUnsafe();
constexpr size_t title_entry_size = sizeof(FileSys::LanguageEntry); constexpr size_t title_entry_size = sizeof(FileSys::LanguageEntry);
@@ -363,9 +354,8 @@ void IReadOnlyApplicationControlDataInterface::ListApplicationTitle(HLERequestCo
auto& memory = system.ApplicationMemory(); auto& memory = system.ApplicationMemory();
const auto t_mem_address = t_mem->GetSourceAddress(); const auto t_mem_address = t_mem->GetSourceAddress();
for (size_t i = 0; i < app_count; ++i) { for (size_t i = 0; i < app_count; ++i) {
const u64 app_id = application_ids[i]; const u64 app_id = app_ids_buffer[i];
const FileSys::PatchManager pm{app_id, system.GetFileSystemController(), const FileSys::PatchManager pm{app_id, system.GetFileSystemController(), system.GetContentProvider()};
system.GetContentProvider()};
const auto control = pm.GetControlMetadata(); const auto control = pm.GetControlMetadata();
FileSys::LanguageEntry entry{}; FileSys::LanguageEntry entry{};
if (control.first != nullptr) { if (control.first != nullptr) {
@@ -90,7 +90,7 @@ template<>
code.shl(tmp, int(ctx.conf.page_table_log2_stride)); code.shl(tmp, int(ctx.conf.page_table_log2_stride));
code.mov(page, qword[r14 + tmp.cvt64()]); code.mov(page, qword[r14 + tmp.cvt64()]);
} else { } else {
code.mov(page, qword[r14 + tmp.cvt64() * int(1 << ctx.conf.page_table_log2_stride)]); code.mov(page, qword[r14 + tmp.cvt64() * int(ctx.conf.page_table_log2_stride)]);
} }
// check for marked bit, use as unmapped if marked // check for marked bit, use as unmapped if marked
@@ -2850,6 +2850,8 @@ Sampler::VariantKey Sampler::MakeKey(const ImageView& image_view, bool is_depth)
VariantKey key{}; VariantKey key{};
key.reduce_anisotropy = has_added_anisotropy && !image_view.SupportsAnisotropy(); key.reduce_anisotropy = has_added_anisotropy && !image_view.SupportsAnisotropy();
key.force_nearest = has_linear_filtering && IsPixelFormatInteger(image_view.format); key.force_nearest = has_linear_filtering && IsPixelFormatInteger(image_view.format);
key.drop_depth_comparison =
is_depth && has_depth_comparison && !image_view.SupportsDepthComparison();
key.drop_reduction = has_minmax_reduction && !image_view.SupportsMinmaxFilter(); key.drop_reduction = has_minmax_reduction && !image_view.SupportsMinmaxFilter();
key.drop_custom_border = has_custom_border_colors && image_view.RequiresBorderColorFormat(); key.drop_custom_border = has_custom_border_colors && image_view.RequiresBorderColorFormat();
key.srgb_border = has_srgb_border_color && IsPixelFormatSRGB(image_view.format); key.srgb_border = has_srgb_border_color && IsPixelFormatSRGB(image_view.format);
@@ -2927,6 +2929,9 @@ VkSampler Sampler::Emplace(VariantKey key) {
create_info.anisotropyEnable = static_cast<VkBool32>(default_anisotropy > 1.0f); create_info.anisotropyEnable = static_cast<VkBool32>(default_anisotropy > 1.0f);
create_info.maxAnisotropy = default_anisotropy; create_info.maxAnisotropy = default_anisotropy;
} }
if (key.drop_depth_comparison) {
create_info.compareEnable = VK_FALSE;
}
if (!custom_border) { if (!custom_border) {
create_info.borderColor = ConvertBorderColor(color); create_info.borderColor = ConvertBorderColor(color);
} }
@@ -536,6 +536,7 @@ private:
struct VariantKey { struct VariantKey {
bool reduce_anisotropy; bool reduce_anisotropy;
bool force_nearest; bool force_nearest;
bool drop_depth_comparison;
bool drop_reduction; bool drop_reduction;
bool drop_custom_border; bool drop_custom_border;
bool srgb_border; bool srgb_border;
+4
View File
@@ -444,6 +444,10 @@ if (YUZU_ROOM)
target_link_libraries(yuzu PRIVATE yuzu-room) target_link_libraries(yuzu PRIVATE yuzu-room)
endif() endif()
if (LINKER STREQUAL "lld")
target_link_options(yuzu-cmd PRIVATE "LINKER:--icf=all")
endif()
if (NOT MSVC AND (APPLE OR NOT YUZU_STATIC_BUILD)) if (NOT MSVC AND (APPLE OR NOT YUZU_STATIC_BUILD))
# needed for vma # needed for vma
target_compile_options(yuzu PRIVATE target_compile_options(yuzu PRIVATE
+4
View File
@@ -67,6 +67,10 @@ endif()
create_target_directory_groups(yuzu-cmd) create_target_directory_groups(yuzu-cmd)
if (LINKER STREQUAL "lld")
target_link_options(yuzu-cmd PRIVATE "LINKER:--icf=all")
endif()
# needed for vma # needed for vma
if (NOT MSVC) if (NOT MSVC)
target_compile_options(yuzu-cmd PRIVATE target_compile_options(yuzu-cmd PRIVATE