mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-16 16:24:51 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac35358b3f | |||
| 7bf95be2c2 | |||
| 4ce45b3b37 | |||
| fd34024f0e | |||
| d76f8f91c4 | |||
| a7061eb4c8 | |||
| fa4e7c6992 | |||
| b77308ced6 |
@@ -110,7 +110,6 @@ add_library(
|
|||||||
socket_types.h
|
socket_types.h
|
||||||
sparse_large_vector.cpp
|
sparse_large_vector.cpp
|
||||||
sparse_large_vector.h
|
sparse_large_vector.h
|
||||||
spin_lock.h
|
|
||||||
stb.cpp
|
stb.cpp
|
||||||
stb.h
|
stb.h
|
||||||
steady_clock.cpp
|
steady_clock.cpp
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 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
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <intrin.h>
|
|
||||||
#elif defined(ARCHITECTURE_x86_64)
|
|
||||||
#include <xmmintrin.h>
|
|
||||||
#endif
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
namespace Common {
|
|
||||||
|
|
||||||
/// @brief A lock similar to mutex that forces a thread to spin wait instead calling the
|
|
||||||
/// supervisor. Should be used on short sequences of code.
|
|
||||||
struct SpinLock {
|
|
||||||
SpinLock() noexcept = default;
|
|
||||||
SpinLock(const SpinLock&) noexcept = delete;
|
|
||||||
SpinLock& operator=(const SpinLock&) noexcept = delete;
|
|
||||||
SpinLock(SpinLock&&) noexcept = delete;
|
|
||||||
SpinLock& operator=(SpinLock&&) noexcept = delete;
|
|
||||||
|
|
||||||
inline void lock() noexcept {
|
|
||||||
while (lck.test_and_set(std::memory_order_acquire)) {
|
|
||||||
#if defined(ARCHITECTURE_x86_64)
|
|
||||||
_mm_pause();
|
|
||||||
#elif defined(ARCHITECTURE_arm64) && defined(_MSC_VER)
|
|
||||||
__yield();
|
|
||||||
#elif defined(ARCHITECTURE_arm64)
|
|
||||||
asm("yield");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void unlock() noexcept {
|
|
||||||
lck.clear(std::memory_order_release);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline bool try_lock() noexcept {
|
|
||||||
return !lck.test_and_set(std::memory_order_acquire);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::atomic_flag lck = ATOMIC_FLAG_INIT;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Common
|
|
||||||
+2
-2
@@ -208,9 +208,9 @@ UUID UUID::MakeRandomRFC4122V4() {
|
|||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID UUID::MakeRFC4122V5(std::span<u8, 20> sha1) {
|
UUID UUID::MakeRFC4122V5(std::span<u8, 16> sha1) {
|
||||||
UUID uuid{};
|
UUID uuid{};
|
||||||
std::memcpy(&uuid.uuid, sha1.data(), sizeof(UUID));
|
std::memcpy(&uuid.uuid, sha1.data(), sha1.size());
|
||||||
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
@@ -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, 20> sha1);
|
[[nodiscard]] static UUID MakeRFC4122V5(std::span<u8, 16> sha1);
|
||||||
|
|
||||||
friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default;
|
friend constexpr bool operator==(const UUID& lhs, const UUID& rhs) = default;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -796,6 +796,8 @@ 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
|
||||||
@@ -810,8 +812,6 @@ 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
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#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 {
|
||||||
|
|
||||||
@@ -29,23 +30,39 @@ 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{};
|
||||||
|
|
||||||
// Disconnect Handheld first.
|
// reserve existing AND valid players before filling slots. include Handheld, but not other
|
||||||
|
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);
|
||||||
handheld->Disconnect();
|
if (!keep_connected[hid_core.available_controllers - 2]) 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);
|
||||||
|
|
||||||
// First, disconnect all controllers regardless of the value of keep_controllers_connected.
|
if (keep_connected[index]) continue;
|
||||||
// This makes it easy to connect the desired controllers.
|
|
||||||
controller->Disconnect();
|
controller->Disconnect();
|
||||||
|
|
||||||
// Only connect the minimum number of required players.
|
// only add players still needed to reach the minimum
|
||||||
if (index >= min_supported_players) {
|
if (num_selected_players >= min_supported_players) continue;
|
||||||
continue;
|
++num_selected_players;
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
||||||
|
|||||||
@@ -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-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
#include "common/atomic_ops.h"
|
#include "common/atomic_ops.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/spin_lock.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
@@ -30,7 +29,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr KSlabHeapImpl() = default;
|
KSlabHeapImpl() = default;
|
||||||
|
|
||||||
void Initialize() {
|
void Initialize() {
|
||||||
ASSERT(m_head == nullptr);
|
ASSERT(m_head == nullptr);
|
||||||
@@ -68,7 +67,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic<Node*> m_head{};
|
std::atomic<Node*> m_head{};
|
||||||
Common::SpinLock m_lock;
|
std::mutex m_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "common/intrusive_red_black_tree.h"
|
#include "common/intrusive_red_black_tree.h"
|
||||||
#include "common/scratch_buffer.h"
|
#include "common/scratch_buffer.h"
|
||||||
#include "common/spin_lock.h"
|
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
#include "core/hle/kernel/k_affinity_mask.h"
|
#include "core/hle/kernel/k_affinity_mask.h"
|
||||||
#include "core/hle/kernel/k_light_lock.h"
|
#include "core/hle/kernel/k_light_lock.h"
|
||||||
@@ -920,7 +919,7 @@ private:
|
|||||||
bool m_resource_limit_release_hint{};
|
bool m_resource_limit_release_hint{};
|
||||||
bool m_is_kernel_address_key{};
|
bool m_is_kernel_address_key{};
|
||||||
StackParameters m_stack_parameters{};
|
StackParameters m_stack_parameters{};
|
||||||
Common::SpinLock m_context_guard{};
|
std::mutex m_context_guard{};
|
||||||
|
|
||||||
// For emulation
|
// For emulation
|
||||||
std::shared_ptr<Common::Fiber> m_host_context{};
|
std::shared_ptr<Common::Fiber> m_host_context{};
|
||||||
|
|||||||
@@ -23,12 +23,6 @@ constexpr std::size_t profile_username_size{32};
|
|||||||
using ProfileUsername = std::array<u8, profile_username_size>;
|
using ProfileUsername = std::array<u8, profile_username_size>;
|
||||||
using UserIDArray = std::array<Common::UUID, MAX_USERS>;
|
using UserIDArray = std::array<Common::UUID, MAX_USERS>;
|
||||||
|
|
||||||
// This is nn::account::Uid
|
|
||||||
struct Uid {
|
|
||||||
std::array<u8, 0x10> unk0;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(Uid) == 0x10);
|
|
||||||
|
|
||||||
/// Contains extra data related to a user.
|
/// Contains extra data related to a user.
|
||||||
/// TODO: RE this structure
|
/// TODO: RE this structure
|
||||||
struct UserData {
|
struct UserData {
|
||||||
|
|||||||
@@ -347,21 +347,22 @@ 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, ResultUnknown);
|
R_UNLESS(out_pseudo_device_id != nullptr, 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);
|
||||||
u8 hash[EVP_MAX_MD_SIZE];
|
R_UNLESS(res.first != nullptr, ResultUnknown);
|
||||||
|
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, &hash_len);
|
EVP_DigestFinal_ex(ctx, hash.data(), &hash_len);
|
||||||
EVP_MD_CTX_free(ctx);
|
EVP_MD_CTX_free(ctx);
|
||||||
*out_pseudo_device_id = Common::UUID::MakeRFC4122V5(std::span<u8, 20>{hash, std::size(hash)});
|
*out_pseudo_device_id = Common::UUID::MakeRFC4122V5(std::span<u8, 16>{hash.begin(), hash.begin() + 16});
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,9 +154,6 @@ FSP_SRV::FSP_SRV(Core::System& system_)
|
|||||||
{720, nullptr, "AbandonAccessFailure"},
|
{720, nullptr, "AbandonAccessFailure"},
|
||||||
{800, nullptr, "GetAndClearFileSystemProxyErrorInfo"},
|
{800, nullptr, "GetAndClearFileSystemProxyErrorInfo"},
|
||||||
{810, nullptr, "RegisterProgramIndexMapInfo"},
|
{810, nullptr, "RegisterProgramIndexMapInfo"},
|
||||||
{820, nullptr, "GetContentStorageInfoIndex"},
|
|
||||||
{830, nullptr, "EncryptStreamPlaySaveData"},
|
|
||||||
{831, nullptr, "DecryptStreamPlaySaveData"},
|
|
||||||
{1000, nullptr, "SetBisRootForHost"},
|
{1000, nullptr, "SetBisRootForHost"},
|
||||||
{1001, nullptr, "SetSaveDataSize"},
|
{1001, nullptr, "SetSaveDataSize"},
|
||||||
{1002, nullptr, "SetSaveDataRootPath"},
|
{1002, nullptr, "SetSaveDataRootPath"},
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
constexpr Result ResultNotSupported{ErrorModule::HIPC, 1};
|
|
||||||
constexpr Result ResultSessionClosed{ErrorModule::HIPC, 301};
|
constexpr Result ResultSessionClosed{ErrorModule::HIPC, 301};
|
||||||
|
|
||||||
struct ResponseBuilder {
|
struct ResponseBuilder {
|
||||||
|
|||||||
@@ -6,16 +6,10 @@
|
|||||||
|
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/k_client_session.h"
|
|
||||||
#include "core/hle/result.h"
|
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
|
||||||
#include "core/hle/service/ipc_helpers.h"
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
#include "core/hle/service/ngc/ngc.h"
|
#include "core/hle/service/ngc/ngc.h"
|
||||||
#include "core/hle/service/server_manager.h"
|
#include "core/hle/service/server_manager.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "frontend_common/firmware_manager.h"
|
|
||||||
|
|
||||||
namespace Service::NGC {
|
namespace Service::NGC {
|
||||||
|
|
||||||
@@ -172,123 +166,12 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SaveDataHandle {
|
|
||||||
u64 unk0;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(SaveDataHandle) == 0x08);
|
|
||||||
|
|
||||||
class IUserShimScopedObject final : public ServiceFramework<IUserShimScopedObject> {
|
|
||||||
public:
|
|
||||||
explicit IUserShimScopedObject(Core::System& system_) : ServiceFramework(system_, "IUserShimScopedObject") {
|
|
||||||
// clang-format off
|
|
||||||
static const FunctionInfo functions[] = {
|
|
||||||
{450, nullptr, "InitializeForSaveData"},
|
|
||||||
{451, nullptr, "FinalizeForSaveData"},
|
|
||||||
{452, D<&IUserShimScopedObject::OpenSaveData>, "OpenSaveData"},
|
|
||||||
{453, nullptr, "CloseSaveData"},
|
|
||||||
{454, D<&IUserShimScopedObject::ReadSaveSlot>, "ReadSaveSlot"},
|
|
||||||
{455, D<&IUserShimScopedObject::WriteSaveSlot>, "WriteSaveSlot"},
|
|
||||||
{456, nullptr, "FlushSaveSlot"},
|
|
||||||
{457, nullptr, "CommitSaveData"},
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
RegisterHandlers(functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result OpenSaveData(Account::Uid unk0, Out<SaveDataHandle> unk1) {
|
|
||||||
LOG_WARNING(Service_NGC, "stubbed");
|
|
||||||
R_THROW(IPC::ResultNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ReadSaveSlot(s32 offset, SaveDataHandle handle, OutBuffer<BufferAttr_HipcAutoSelect> out_data, Out<u32> out_size) {
|
|
||||||
LOG_WARNING(Service_NGC, "stubbed");
|
|
||||||
R_THROW(IPC::ResultNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result WriteSaveSlot(s32 offset, SaveDataHandle handle, InBuffer<BufferAttr_HipcAutoSelect> out_data) {
|
|
||||||
LOG_WARNING(Service_NGC, "stubbed");
|
|
||||||
// to implement
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IUserService final : public ServiceFramework<IUserService> {
|
|
||||||
public:
|
|
||||||
explicit IUserService(Core::System& system_) : ServiceFramework(system_, "stpl:u") {
|
|
||||||
// clang-format off
|
|
||||||
static const FunctionInfo functions[] = {
|
|
||||||
{0 , D<&IUserService::Cmd0>, "Cmd0"},
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
RegisterHandlers(functions);
|
|
||||||
}
|
|
||||||
Result Cmd0(u32 unk0, OutInterface<IUserShimScopedObject> out_interface) {
|
|
||||||
LOG_WARNING(Service_NGC, "stubbed");
|
|
||||||
*out_interface = std::make_shared<IUserShimScopedObject>(system);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ISystemShimScopedObject final : public ServiceFramework<ISystemShimScopedObject> {
|
|
||||||
public:
|
|
||||||
explicit ISystemShimScopedObject(Core::System& system_) : ServiceFramework(system_, "ISystemShimScopedObject") {
|
|
||||||
// clang-format off
|
|
||||||
static const FunctionInfo functions[] = {
|
|
||||||
{106, nullptr, "Cmd106"},
|
|
||||||
{107, nullptr, "Cmd107"},
|
|
||||||
{108, D<&ISystemShimScopedObject::Cmd108>, "Cmd108"},
|
|
||||||
{207, nullptr, "Cmd207"},
|
|
||||||
{208, D<&ISystemShimScopedObject::Cmd208>, "Cmd208"},
|
|
||||||
{209, nullptr, "Cmd209"},
|
|
||||||
{210, nullptr, "Cmd210"},
|
|
||||||
{211, nullptr, "Cmd211"},
|
|
||||||
{212, nullptr, "Cmd212"},
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
RegisterHandlers(functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result Cmd108() {
|
|
||||||
LOG_WARNING(Service_NGC, "stubbed");
|
|
||||||
R_THROW(IPC::ResultNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result Cmd208(Out<std::array<u8, 0x20>> unk0) {
|
|
||||||
LOG_WARNING(Service_NGC, "stubbed");
|
|
||||||
R_THROW(IPC::ResultNotSupported);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ISystemService final : public ServiceFramework<ISystemService> {
|
|
||||||
public:
|
|
||||||
explicit ISystemService(Core::System& system_) : ServiceFramework(system_, "stpl:sys") {
|
|
||||||
// clang-format off
|
|
||||||
static const FunctionInfo functions[] = {
|
|
||||||
{0 , D<&ISystemService::Cmd0>, "Cmd0"},
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
RegisterHandlers(functions);
|
|
||||||
}
|
|
||||||
Result Cmd0(OutInterface<ISystemShimScopedObject> out_interface) {
|
|
||||||
LOG_WARNING(Service_NGC, "stubbed");
|
|
||||||
*out_interface = std::make_shared<ISystemShimScopedObject>(system);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void LoopProcess(Core::System& system) {
|
void LoopProcess(Core::System& system) {
|
||||||
auto server_manager = std::make_unique<ServerManager>(system);
|
auto server_manager = std::make_unique<ServerManager>(system);
|
||||||
|
|
||||||
server_manager->RegisterNamedService("ngct:u", std::make_shared<IService>(system), 4);
|
server_manager->RegisterNamedService("ngct:u", std::make_shared<IService>(system), 4);
|
||||||
server_manager->RegisterNamedService("ngct:s", std::make_shared<IServiceWithManagementApi>(system), 4);
|
server_manager->RegisterNamedService("ngct:s", std::make_shared<IServiceWithManagementApi>(system), 4);
|
||||||
server_manager->RegisterNamedService("ngc:u", std::make_shared<NgcServiceImpl>(system), 4);
|
server_manager->RegisterNamedService("ngc:u", std::make_shared<NgcServiceImpl>(system), 4);
|
||||||
|
|
||||||
// +23.0.0
|
|
||||||
if (FirmwareManager::GetFirmwareVersion(system).first.major >= 23) {
|
|
||||||
server_manager->RegisterNamedService("stpl:u", std::make_shared<IUserService>(system), 4);
|
|
||||||
server_manager->RegisterNamedService("stpl:sys", std::make_shared<ISystemService>(system), 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerManager::RunServer(std::move(server_manager));
|
ServerManager::RunServer(std::move(server_manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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/i_async_result.h"
|
#include "core/hle/service/ns/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"
|
||||||
|
|||||||
+1
-1
@@ -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/i_async_result.h"
|
#include "core/hle/service/ns/async_result.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@@ -311,27 +311,30 @@ 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()};
|
||||||
const auto control = pm.GetControlMetadata();
|
if (const auto control = pm.GetControlMetadata(); control.second) {
|
||||||
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()};
|
||||||
const auto control = pm.GetControlMetadata();
|
if (const auto control = pm.GetControlMetadata(); control.second) {
|
||||||
auto const full_size = control.second->GetSize();
|
if (auto const full_size = control.second->GetSize(); full_size > 0) {
|
||||||
if (full_size > 0) {
|
std::vector<u8> full_icon_data(full_size);
|
||||||
full_icon_data.resize(full_size);
|
control.second->Read(full_icon_data.data(), full_size, 0);
|
||||||
control.second->Read(full_icon_data.data(), full_size, 0);
|
memory.WriteBlock(t_mem_address + out_length, full_icon_data.data(), full_size);
|
||||||
memory.WriteBlock(t_mem_address + out_length, full_icon_data.data(), full_size);
|
out_length += full_size;
|
||||||
out_length += full_size;
|
ASSERT(out_length <= t_mem->GetSize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,6 +348,12 @@ 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);
|
||||||
@@ -354,8 +363,9 @@ 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 = app_ids_buffer[i];
|
const u64 app_id = application_ids[i];
|
||||||
const FileSys::PatchManager pm{app_id, system.GetFileSystemController(), system.GetContentProvider()};
|
const FileSys::PatchManager pm{app_id, system.GetFileSystemController(),
|
||||||
|
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(ctx.conf.page_table_log2_stride)]);
|
code.mov(page, qword[r14 + tmp.cvt64() * int(1 << 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,8 +2850,6 @@ 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);
|
||||||
@@ -2929,9 +2927,6 @@ 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,7 +536,6 @@ 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;
|
||||||
|
|||||||
Reference in New Issue
Block a user