Compare commits

..

21 Commits

Author SHA1 Message Date
Liam
023b9b38cc general: fix apple clang build 2023-08-09 22:38:37 -04:00
liamwhite
85e3575496 Merge pull request #11216 from lat9nq/no-mesa-astc
gl_device: Detect Mesa to disable their ASTC
2023-08-07 11:34:22 -04:00
liamwhite
7f55c377b0 Merge pull request #11217 from german77/olsc
service: olsc: Implement IOlscServiceForSystemService ITransferTaskListController interfaces for QLaunch
2023-08-07 11:34:14 -04:00
liamwhite
9893a4d918 Merge pull request #11221 from german77/pctl
service: pctl: Implement functions needed for QLaunch
2023-08-07 11:34:07 -04:00
liamwhite
bed2fc8707 Merge pull request #11224 from german77/audio
service: audctl: Stub functions needed by Qlaunch
2023-08-07 11:33:55 -04:00
german77
8d2f0dc707 service: audctl: Stub functions needed by Qlaunch 2023-08-05 20:16:26 -06:00
lat9nq
cb0b8442f0 gl_device: Filter more specifically for slow ASTC
Adds a check to find if the renderer is Intel DG (i.e. DG2).

gl_device: Detect Mesa to disable their ASTC

In our testing, our own ASTC decoder has shown itself to perform faster
than the included one from the driver. Disable theirs when Mesa is
detected.

Mesa detection depends on the vendor string. Some drivers never appear
outside of *nix contexts, so only check those in the *nix context.

gl_device: Internalize Intel DG detection
2023-08-05 15:19:16 -04:00
german77
089e385944 service: olsc: Implement IOlscServiceForSystemService ITransferTaskListController interfaces for QLaunch 2023-08-05 11:47:51 -06:00
german77
0d470b57ed service: pctl: Implement functions needed for QLaunch 2023-08-05 11:27:41 -06:00
liamwhite
755f45a522 Merge pull request #11213 from RngValue/master
📝 Update README.md
2023-08-05 12:58:45 -04:00
liamwhite
4533769f7f Merge pull request #11212 from Kelebek1/shader_stuff
Fix various misc pipeline/shader things
2023-08-05 12:58:39 -04:00
liamwhite
00d9a9c44e Merge pull request #11210 from german77/settings
service: set: Implement system settings for Qlaunch
2023-08-05 12:58:32 -04:00
liamwhite
35bdd5fff3 Merge pull request #11208 from german77/interface
service: am: Fix wrong interface ILibraryAppletSelfAccessor
2023-08-05 12:58:20 -04:00
Narr the Reg
7707768f80 service: set: Add more system settings and address comments 2023-08-04 17:20:40 -06:00
RngValue
ae19eb1e10 Merge pull request #1 from RngValue/RngValue-patch-1
📝 Update README.md (A potential grammar error and a missing period)
2023-08-04 18:18:39 +02:00
RngValue
a09507f271 📝 Update README.md 2023-08-04 17:58:49 +02:00
liamwhite
369fcadf08 Merge pull request #11209 from ameerj/subgroup_size_control
vulkan_device: Fix VK_EXT_subgroup_size_control detection
2023-08-03 10:15:12 -04:00
Narr the Reg
4bd4a95d84 service: set: Implement system settings for Qlaunch 2023-08-02 22:33:42 -06:00
Ameer J
cd80cbc420 vulkan_device: Fix subgroup_size_control detection on Vulkan 1.3 2023-08-02 20:45:03 -04:00
Ameer J
c7c44dc238 vulkan_device: Fix VK_EXT_subgroup_size_control detection 2023-08-02 19:25:14 -04:00
Narr the Reg
dd1cbd9c56 service: am: Fix wrong interface 2023-08-02 13:00:30 -06:00
20 changed files with 1256 additions and 229 deletions

View File

@@ -40,7 +40,7 @@ It is written in C++ with portability in mind, and we actively maintain builds f
The emulator is capable of running most commercial games at full speed, provided you meet the [necessary hardware requirements](https://yuzu-emu.org/help/quickstart/#hardware-requirements).
For a full list of games yuzu support, please visit our [Compatibility page](https://yuzu-emu.org/game/)
For a full list of games yuzu supports, please visit our [Compatibility page](https://yuzu-emu.org/game/).
Check out our [website](https://yuzu-emu.org/) for the latest news on exciting features, monthly progress reports, and more!

View File

@@ -1,7 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <functional>
#include <string>
#include <vector>
#include "common/settings_common.h"
namespace Settings {

View File

@@ -12,8 +12,8 @@ namespace Settings {
template <typename T>
struct EnumMetadata {
static constexpr std::vector<std::pair<std::string, T>> Canonicalizations();
static constexpr u32 Index();
static std::vector<std::pair<std::string, T>> Canonicalizations();
static u32 Index();
};
#define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__))
@@ -66,11 +66,11 @@ struct EnumMetadata {
#define ENUM(NAME, ...) \
enum class NAME : u32 { __VA_ARGS__ }; \
template <> \
constexpr std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \
inline std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \
return {PAIR(NAME, __VA_ARGS__)}; \
} \
template <> \
constexpr u32 EnumMetadata<NAME>::Index() { \
inline u32 EnumMetadata<NAME>::Index() { \
return __COUNTER__; \
}
@@ -85,7 +85,7 @@ enum class AudioEngine : u32 {
};
template <>
constexpr std::vector<std::pair<std::string, AudioEngine>>
inline std::vector<std::pair<std::string, AudioEngine>>
EnumMetadata<AudioEngine>::Canonicalizations() {
return {
{"auto", AudioEngine::Auto},
@@ -96,7 +96,7 @@ EnumMetadata<AudioEngine>::Canonicalizations() {
}
template <>
constexpr u32 EnumMetadata<AudioEngine>::Index() {
inline u32 EnumMetadata<AudioEngine>::Index() {
// This is just a sufficiently large number that is more than the number of other enums declared
// here
return 100;
@@ -147,7 +147,7 @@ ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
template <typename Type>
constexpr std::string CanonicalizeEnum(Type id) {
inline std::string CanonicalizeEnum(Type id) {
const auto group = EnumMetadata<Type>::Canonicalizations();
for (auto& [name, value] : group) {
if (value == id) {
@@ -158,7 +158,7 @@ constexpr std::string CanonicalizeEnum(Type id) {
}
template <typename Type>
constexpr Type ToEnum(const std::string& canonicalization) {
inline Type ToEnum(const std::string& canonicalization) {
const auto group = EnumMetadata<Type>::Canonicalizations();
for (auto& [name, value] : group) {
if (name == canonicalization) {

View File

@@ -190,7 +190,7 @@ public:
}
}
[[nodiscard]] std::string constexpr Canonicalize() const override final {
[[nodiscard]] std::string Canonicalize() const override final {
if constexpr (std::is_enum_v<Type>) {
return CanonicalizeEnum(this->GetValue());
} else {
@@ -256,11 +256,11 @@ public:
* @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
* @param other_setting_ A second Setting to associate to this one in metadata
*/
template <typename T = BasicSetting>
explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name,
Category category_, u32 specialization_ = Specialization::Default,
bool save_ = true, bool runtime_modifiable_ = false,
BasicSetting* other_setting_ = nullptr)
requires(!ranged)
typename std::enable_if<!ranged, T*>::type other_setting_ = nullptr)
: Setting<Type, false>{
linkage, default_val, name, category_, specialization_,
save_, runtime_modifiable_, other_setting_} {
@@ -282,12 +282,12 @@ public:
* @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
* @param other_setting_ A second Setting to associate to this one in metadata
*/
template <typename T = BasicSetting>
explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val,
const Type& max_val, const std::string& name, Category category_,
u32 specialization_ = Specialization::Default, bool save_ = true,
bool runtime_modifiable_ = false,
BasicSetting* other_setting_ = nullptr)
requires(ranged)
typename std::enable_if<ranged, T*>::type other_setting_ = nullptr)
: Setting<Type, true>{linkage, default_val, min_val,
max_val, name, category_,
specialization_, save_, runtime_modifiable_,

View File

@@ -1317,6 +1317,50 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
rb.PushIpcInterface<IStorage>(system, std::move(memory));
}
ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
: ServiceFramework{system_, "ILibraryAppletSelfAccessor"} {
static const FunctionInfo functions[] = {
{0, nullptr, "PopInData"},
{1, nullptr, "PushOutData"},
{2, nullptr, "PopInteractiveInData"},
{3, nullptr, "PushInteractiveOutData"},
{5, nullptr, "GetPopInDataEvent"},
{6, nullptr, "GetPopInteractiveInDataEvent"},
{10, nullptr, "ExitProcessAndReturn"},
{11, nullptr, "GetLibraryAppletInfo"},
{12, nullptr, "GetMainAppletIdentityInfo"},
{13, nullptr, "CanUseApplicationCore"},
{14, nullptr, "GetCallerAppletIdentityInfo"},
{15, nullptr, "GetMainAppletApplicationControlProperty"},
{16, nullptr, "GetMainAppletStorageId"},
{17, nullptr, "GetCallerAppletIdentityInfoStack"},
{18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"},
{19, nullptr, "GetDesirableKeyboardLayout"},
{20, nullptr, "PopExtraStorage"},
{25, nullptr, "GetPopExtraStorageEvent"},
{30, nullptr, "UnpopInData"},
{31, nullptr, "UnpopExtraStorage"},
{40, nullptr, "GetIndirectLayerProducerHandle"},
{50, nullptr, "ReportVisibleError"},
{51, nullptr, "ReportVisibleErrorWithErrorContext"},
{60, nullptr, "GetMainAppletApplicationDesiredLanguage"},
{70, nullptr, "GetCurrentApplicationId"},
{80, nullptr, "RequestExitToSelf"},
{90, nullptr, "CreateApplicationAndPushAndRequestToLaunch"},
{100, nullptr, "CreateGameMovieTrimmer"},
{101, nullptr, "ReserveResourceForMovieOperation"},
{102, nullptr, "UnreserveResourceForMovieOperation"},
{110, nullptr, "GetMainAppletAvailableUsers"},
{120, nullptr, "GetLaunchStorageInfoForDebug"},
{130, nullptr, "GetGpuErrorDetectedSystemEvent"},
{140, nullptr, "SetApplicationMemoryReservation"},
{150, nullptr, "ShouldSetGpuTimeSliceManually"},
};
RegisterHandlers(functions);
}
ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default;
IApplicationFunctions::IApplicationFunctions(Core::System& system_)
: ServiceFramework{system_, "IApplicationFunctions"}, service_context{system,
"IApplicationFunctions"} {

View File

@@ -22,30 +22,6 @@ class Nvnflinger;
namespace Service::AM {
// This is nn::settings::Language
enum SystemLanguage {
Japanese = 0,
English = 1, // en-US
French = 2,
German = 3,
Italian = 4,
Spanish = 5,
Chinese = 6,
Korean = 7,
Dutch = 8,
Portuguese = 9,
Russian = 10,
Taiwanese = 11,
BritishEnglish = 12, // en-GB
CanadianFrench = 13,
LatinAmericanSpanish = 14, // es-419
// 4.0.0+
SimplifiedChinese = 15,
TraditionalChinese = 16,
// 10.1.0+
BrazilianPortuguese = 17,
};
class AppletMessageQueue {
public:
// This is nn::am::AppletMessage
@@ -314,6 +290,12 @@ private:
void CreateHandleStorage(HLERequestContext& ctx);
};
class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> {
public:
explicit ILibraryAppletSelfAccessor(Core::System& system_);
~ILibraryAppletSelfAccessor() override;
};
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
public:
explicit IApplicationFunctions(Core::System& system_);

View File

@@ -26,8 +26,10 @@ public:
{4, &ILibraryAppletProxy::GetDisplayController, "GetDisplayController"},
{10, &ILibraryAppletProxy::GetProcessWindingController, "GetProcessWindingController"},
{11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
{20, &ILibraryAppletProxy::GetApplicationFunctions, "GetApplicationFunctions"},
{20, &ILibraryAppletProxy::OpenLibraryAppletSelfAccessor, "OpenLibraryAppletSelfAccessor"},
{21, nullptr, "GetAppletCommonFunctions"},
{22, nullptr, "GetHomeMenuFunctions"},
{23, nullptr, "GetGlobalStateController"},
{1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"},
};
// clang-format on
@@ -100,12 +102,12 @@ private:
rb.PushIpcInterface<ILibraryAppletCreator>(system);
}
void GetApplicationFunctions(HLERequestContext& ctx) {
void OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IApplicationFunctions>(system);
rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system);
}
Nvnflinger::Nvnflinger& nvnflinger;

View File

@@ -22,13 +22,13 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
{9, nullptr, "GetAudioOutputMode"},
{10, nullptr, "SetAudioOutputMode"},
{11, nullptr, "SetForceMutePolicy"},
{12, nullptr, "GetForceMutePolicy"},
{13, nullptr, "GetOutputModeSetting"},
{12, &AudCtl::GetForceMutePolicy, "GetForceMutePolicy"},
{13, &AudCtl::GetOutputModeSetting, "GetOutputModeSetting"},
{14, nullptr, "SetOutputModeSetting"},
{15, nullptr, "SetOutputTarget"},
{16, nullptr, "SetInputTargetForceEnabled"},
{17, nullptr, "SetHeadphoneOutputLevelMode"},
{18, nullptr, "GetHeadphoneOutputLevelMode"},
{18, &AudCtl::GetHeadphoneOutputLevelMode, "GetHeadphoneOutputLevelMode"},
{19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"},
{20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"},
{21, nullptr, "GetAudioOutputTargetForPlayReport"},
@@ -41,7 +41,7 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
{28, nullptr, "GetAudioOutputChannelCountForPlayReport"},
{29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
{30, nullptr, "SetSpeakerAutoMuteEnabled"},
{31, nullptr, "IsSpeakerAutoMuteEnabled"},
{31, &AudCtl::IsSpeakerAutoMuteEnabled, "IsSpeakerAutoMuteEnabled"},
{32, nullptr, "GetActiveOutputTarget"},
{33, nullptr, "GetTargetDeviceInfo"},
{34, nullptr, "AcquireTargetNotification"},
@@ -96,4 +96,42 @@ void AudCtl::GetTargetVolumeMax(HLERequestContext& ctx) {
rb.Push(target_max_volume);
}
void AudCtl::GetForceMutePolicy(HLERequestContext& ctx) {
LOG_WARNING(Audio, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(ForceMutePolicy::Disable);
}
void AudCtl::GetOutputModeSetting(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto value = rp.Pop<u32>();
LOG_WARNING(Audio, "(STUBBED) called, value={}", value);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(AudioOutputMode::PcmAuto);
}
void AudCtl::GetHeadphoneOutputLevelMode(HLERequestContext& ctx) {
LOG_WARNING(Audio, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(HeadphoneOutputLevelMode::Normal);
}
void AudCtl::IsSpeakerAutoMuteEnabled(HLERequestContext& ctx) {
const bool is_speaker_auto_mute_enabled = false;
LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}",
is_speaker_auto_mute_enabled);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(is_speaker_auto_mute_enabled);
}
} // namespace Service::Audio

View File

@@ -17,8 +17,30 @@ public:
~AudCtl() override;
private:
enum class AudioOutputMode {
Invalid,
Pcm1ch,
Pcm2ch,
Pcm6ch,
PcmAuto,
};
enum class ForceMutePolicy {
Disable,
SpeakerMuteOnHeadphoneUnplugged,
};
enum class HeadphoneOutputLevelMode {
Normal,
HighPower,
};
void GetTargetVolumeMin(HLERequestContext& ctx);
void GetTargetVolumeMax(HLERequestContext& ctx);
void GetForceMutePolicy(HLERequestContext& ctx);
void GetOutputModeSetting(HLERequestContext& ctx);
void GetHeadphoneOutputLevelMode(HLERequestContext& ctx);
void IsSpeakerAutoMuteEnabled(HLERequestContext& ctx);
};
} // namespace Service::Audio

View File

@@ -8,15 +8,16 @@
namespace Service::OLSC {
class OLSC final : public ServiceFramework<OLSC> {
class IOlscServiceForApplication final : public ServiceFramework<IOlscServiceForApplication> {
public:
explicit OLSC(Core::System& system_) : ServiceFramework{system_, "olsc:u"} {
explicit IOlscServiceForApplication(Core::System& system_)
: ServiceFramework{system_, "olsc:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &OLSC::Initialize, "Initialize"},
{0, &IOlscServiceForApplication::Initialize, "Initialize"},
{10, nullptr, "VerifySaveDataBackupLicenseAsync"},
{13, &OLSC::GetSaveDataBackupSetting, "GetSaveDataBackupSetting"},
{14, &OLSC::SetSaveDataBackupSettingEnabled, "SetSaveDataBackupSettingEnabled"},
{13, &IOlscServiceForApplication::GetSaveDataBackupSetting, "GetSaveDataBackupSetting"},
{14, &IOlscServiceForApplication::SetSaveDataBackupSettingEnabled, "SetSaveDataBackupSettingEnabled"},
{15, nullptr, "SetCustomData"},
{16, nullptr, "DeleteSaveDataBackupSetting"},
{18, nullptr, "GetSaveDataBackupInfoCache"},
@@ -72,10 +73,155 @@ private:
bool initialized{};
};
class INativeHandleHolder final : public ServiceFramework<INativeHandleHolder> {
public:
explicit INativeHandleHolder(Core::System& system_)
: ServiceFramework{system_, "INativeHandleHolder"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetNativeHandle"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> {
public:
explicit ITransferTaskListController(Core::System& system_)
: ServiceFramework{system_, "ITransferTaskListController"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Unknown0"},
{1, nullptr, "Unknown1"},
{2, nullptr, "Unknown2"},
{3, nullptr, "Unknown3"},
{4, nullptr, "Unknown4"},
{5, &ITransferTaskListController::GetNativeHandleHolder , "GetNativeHandleHolder"},
{6, nullptr, "Unknown6"},
{7, nullptr, "Unknown7"},
{8, nullptr, "GetRemoteStorageController"},
{9, &ITransferTaskListController::GetNativeHandleHolder, "GetNativeHandleHolder2"},
{10, nullptr, "Unknown10"},
{11, nullptr, "Unknown11"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{14, nullptr, "Unknown14"},
{15, nullptr, "Unknown15"},
{16, nullptr, "Unknown16"},
{17, nullptr, "Unknown17"},
{18, nullptr, "Unknown18"},
{19, nullptr, "Unknown19"},
{20, nullptr, "Unknown20"},
{21, nullptr, "Unknown21"},
{22, nullptr, "Unknown22"},
{23, nullptr, "Unknown23"},
{24, nullptr, "Unknown24"},
{25, nullptr, "Unknown25"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void GetNativeHandleHolder(HLERequestContext& ctx) {
LOG_INFO(Service_OLSC, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<INativeHandleHolder>(system);
}
};
class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> {
public:
explicit IOlscServiceForSystemService(Core::System& system_)
: ServiceFramework{system_, "olsc:s"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IOlscServiceForSystemService::OpenTransferTaskListController, "OpenTransferTaskListController"},
{1, nullptr, "OpenRemoteStorageController"},
{2, nullptr, "OpenDaemonController"},
{10, nullptr, "Unknown10"},
{11, nullptr, "Unknown11"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{100, nullptr, "ListLastTransferTaskErrorInfo"},
{101, nullptr, "GetLastErrorInfoCount"},
{102, nullptr, "RemoveLastErrorInfoOld"},
{103, nullptr, "GetLastErrorInfo"},
{104, nullptr, "GetLastErrorEventHolder"},
{105, nullptr, "GetLastTransferTaskErrorInfo"},
{200, nullptr, "GetDataTransferPolicyInfo"},
{201, nullptr, "RemoveDataTransferPolicyInfo"},
{202, nullptr, "UpdateDataTransferPolicyOld"},
{203, nullptr, "UpdateDataTransferPolicy"},
{204, nullptr, "CleanupDataTransferPolicyInfo"},
{205, nullptr, "RequestDataTransferPolicy"},
{300, nullptr, "GetAutoTransferSeriesInfo"},
{301, nullptr, "UpdateAutoTransferSeriesInfo"},
{400, nullptr, "CleanupSaveDataArchiveInfoType1"},
{900, nullptr, "CleanupTransferTask"},
{902, nullptr, "CleanupSeriesInfoType0"},
{903, nullptr, "CleanupSaveDataArchiveInfoType0"},
{904, nullptr, "CleanupApplicationAutoTransferSetting"},
{905, nullptr, "CleanupErrorHistory"},
{906, nullptr, "SetLastError"},
{907, nullptr, "AddSaveDataArchiveInfoType0"},
{908, nullptr, "RemoveSeriesInfoType0"},
{909, nullptr, "GetSeriesInfoType0"},
{910, nullptr, "RemoveLastErrorInfo"},
{911, nullptr, "CleanupSeriesInfoType1"},
{912, nullptr, "RemoveSeriesInfoType1"},
{913, nullptr, "GetSeriesInfoType1"},
{1000, nullptr, "UpdateIssueOld"},
{1010, nullptr, "Unknown1010"},
{1011, nullptr, "ListIssueInfoOld"},
{1012, nullptr, "GetIssueOld"},
{1013, nullptr, "GetIssue2Old"},
{1014, nullptr, "GetIssue3Old"},
{1020, nullptr, "RepairIssueOld"},
{1021, nullptr, "RepairIssueWithUserIdOld"},
{1022, nullptr, "RepairIssue2Old"},
{1023, nullptr, "RepairIssue3Old"},
{1024, nullptr, "Unknown1024"},
{1100, nullptr, "UpdateIssue"},
{1110, nullptr, "Unknown1110"},
{1111, nullptr, "ListIssueInfo"},
{1112, nullptr, "GetIssue"},
{1113, nullptr, "GetIssue2"},
{1114, nullptr, "GetIssue3"},
{1120, nullptr, "RepairIssue"},
{1121, nullptr, "RepairIssueWithUserId"},
{1122, nullptr, "RepairIssue2"},
{1123, nullptr, "RepairIssue3"},
{1124, nullptr, "Unknown1124"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void OpenTransferTaskListController(HLERequestContext& ctx) {
LOG_INFO(Service_OLSC, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<ITransferTaskListController>(system);
}
};
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("olsc:u", std::make_shared<OLSC>(system));
server_manager->RegisterNamedService("olsc:u",
std::make_shared<IOlscServiceForApplication>(system));
server_manager->RegisterNamedService("olsc:s",
std::make_shared<IOlscServiceForSystemService>(system));
ServerManager::RunServer(std::move(server_manager));
}

View File

@@ -6,6 +6,7 @@
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/pctl/pctl.h"
#include "core/hle/service/pctl/pctl_module.h"
#include "core/hle/service/server_manager.h"
@@ -24,7 +25,8 @@ constexpr Result ResultNoRestrictionEnabled{ErrorModule::PCTL, 181};
class IParentalControlService final : public ServiceFramework<IParentalControlService> {
public:
explicit IParentalControlService(Core::System& system_, Capability capability_)
: ServiceFramework{system_, "IParentalControlService"}, capability{capability_} {
: ServiceFramework{system_, "IParentalControlService"}, capability{capability_},
service_context{system_, "IParentalControlService"} {
// clang-format off
static const FunctionInfo functions[] = {
{1, &IParentalControlService::Initialize, "Initialize"},
@@ -33,7 +35,7 @@ public:
{1003, nullptr, "ConfirmResumeApplicationPermission"},
{1004, nullptr, "ConfirmSnsPostPermission"},
{1005, nullptr, "ConfirmSystemSettingsPermission"},
{1006, nullptr, "IsRestrictionTemporaryUnlocked"},
{1006, &IParentalControlService::IsRestrictionTemporaryUnlocked, "IsRestrictionTemporaryUnlocked"},
{1007, nullptr, "RevertRestrictionTemporaryUnlocked"},
{1008, nullptr, "EnterRestrictedSystemSettings"},
{1009, nullptr, "LeaveRestrictedSystemSettings"},
@@ -47,14 +49,14 @@ public:
{1017, &IParentalControlService::EndFreeCommunication, "EndFreeCommunication"},
{1018, &IParentalControlService::IsFreeCommunicationAvailable, "IsFreeCommunicationAvailable"},
{1031, &IParentalControlService::IsRestrictionEnabled, "IsRestrictionEnabled"},
{1032, nullptr, "GetSafetyLevel"},
{1032, &IParentalControlService::GetSafetyLevel, "GetSafetyLevel"},
{1033, nullptr, "SetSafetyLevel"},
{1034, nullptr, "GetSafetyLevelSettings"},
{1035, nullptr, "GetCurrentSettings"},
{1035, &IParentalControlService::GetCurrentSettings, "GetCurrentSettings"},
{1036, nullptr, "SetCustomSafetyLevelSettings"},
{1037, nullptr, "GetDefaultRatingOrganization"},
{1038, nullptr, "SetDefaultRatingOrganization"},
{1039, nullptr, "GetFreeCommunicationApplicationListCount"},
{1039, &IParentalControlService::GetFreeCommunicationApplicationListCount, "GetFreeCommunicationApplicationListCount"},
{1042, nullptr, "AddToFreeCommunicationApplicationList"},
{1043, nullptr, "DeleteSettings"},
{1044, nullptr, "GetFreeCommunicationApplicationList"},
@@ -76,7 +78,7 @@ public:
{1206, nullptr, "GetPinCodeLength"},
{1207, nullptr, "GetPinCodeChangedEvent"},
{1208, nullptr, "GetPinCode"},
{1403, nullptr, "IsPairingActive"},
{1403, &IParentalControlService::IsPairingActive, "IsPairingActive"},
{1406, nullptr, "GetSettingsLastUpdated"},
{1411, nullptr, "GetPairingAccountInfo"},
{1421, nullptr, "GetAccountNickname"},
@@ -84,18 +86,18 @@ public:
{1425, nullptr, "RequestPostEvents"},
{1426, nullptr, "GetPostEventInterval"},
{1427, nullptr, "SetPostEventInterval"},
{1432, nullptr, "GetSynchronizationEvent"},
{1432, &IParentalControlService::GetSynchronizationEvent, "GetSynchronizationEvent"},
{1451, nullptr, "StartPlayTimer"},
{1452, nullptr, "StopPlayTimer"},
{1453, nullptr, "IsPlayTimerEnabled"},
{1454, nullptr, "GetPlayTimerRemainingTime"},
{1455, nullptr, "IsRestrictedByPlayTimer"},
{1456, nullptr, "GetPlayTimerSettings"},
{1457, nullptr, "GetPlayTimerEventToRequestSuspension"},
{1458, nullptr, "IsPlayTimerAlarmDisabled"},
{1456, &IParentalControlService::GetPlayTimerSettings, "GetPlayTimerSettings"},
{1457, &IParentalControlService::GetPlayTimerEventToRequestSuspension, "GetPlayTimerEventToRequestSuspension"},
{1458, &IParentalControlService::IsPlayTimerAlarmDisabled, "IsPlayTimerAlarmDisabled"},
{1471, nullptr, "NotifyWrongPinCodeInputManyTimes"},
{1472, nullptr, "CancelNetworkRequest"},
{1473, nullptr, "GetUnlinkedEvent"},
{1473, &IParentalControlService::GetUnlinkedEvent, "GetUnlinkedEvent"},
{1474, nullptr, "ClearUnlinkedEvent"},
{1601, nullptr, "DisableAllFeatures"},
{1602, nullptr, "PostEnableAllFeatures"},
@@ -131,6 +133,12 @@ public:
};
// clang-format on
RegisterHandlers(functions);
synchronization_event =
service_context.CreateEvent("IParentalControlService::SynchronizationEvent");
unlinked_event = service_context.CreateEvent("IParentalControlService::UnlinkedEvent");
request_suspension_event =
service_context.CreateEvent("IParentalControlService::RequestSuspensionEvent");
}
private:
@@ -144,7 +152,7 @@ private:
if (pin_code[0] == '\0') {
return true;
}
if (!settings.is_free_communication_default_on) {
if (!restriction_settings.is_free_communication_default_on) {
return true;
}
// TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here
@@ -160,21 +168,21 @@ private:
if (pin_code[0] == '\0') {
return true;
}
if (!settings.is_stero_vision_restricted) {
if (!restriction_settings.is_stero_vision_restricted) {
return false;
}
return true;
}
void SetStereoVisionRestrictionImpl(bool is_restricted) {
if (settings.disabled) {
if (restriction_settings.disabled) {
return;
}
if (pin_code[0] == '\0') {
return;
}
settings.is_stero_vision_restricted = is_restricted;
restriction_settings.is_stero_vision_restricted = is_restricted;
}
void Initialize(HLERequestContext& ctx) {
@@ -228,6 +236,17 @@ private:
states.free_communication = true;
}
void IsRestrictionTemporaryUnlocked(HLERequestContext& ctx) {
const bool is_temporary_unlocked = false;
LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}",
is_temporary_unlocked);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(is_temporary_unlocked);
}
void ConfirmStereoVisionPermission(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
states.stereo_vision = true;
@@ -268,6 +287,34 @@ private:
rb.Push(pin_code[0] != '\0');
}
void GetSafetyLevel(HLERequestContext& ctx) {
const u32 safety_level = 0;
LOG_WARNING(Service_PCTL, "(STUBBED) called, safety_level={}", safety_level);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(safety_level);
}
void GetCurrentSettings(HLERequestContext& ctx) {
LOG_INFO(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushRaw(restriction_settings);
}
void GetFreeCommunicationApplicationListCount(HLERequestContext& ctx) {
const u32 count = 4;
LOG_WARNING(Service_PCTL, "(STUBBED) called, count={}", count);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(count);
}
void ConfirmStereoVisionRestrictionConfigurable(HLERequestContext& ctx) {
LOG_DEBUG(Service_PCTL, "called");
@@ -300,6 +347,61 @@ private:
}
}
void IsPairingActive(HLERequestContext& ctx) {
const bool is_pairing_active = false;
LOG_WARNING(Service_PCTL, "(STUBBED) called, is_pairing_active={}", is_pairing_active);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(is_pairing_active);
}
void GetSynchronizationEvent(HLERequestContext& ctx) {
LOG_INFO(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(synchronization_event->GetReadableEvent());
}
void GetPlayTimerSettings(HLERequestContext& ctx) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
const PlayTimerSettings timer_settings{};
IPC::ResponseBuilder rb{ctx, 15};
rb.Push(ResultSuccess);
rb.PushRaw(timer_settings);
}
void GetPlayTimerEventToRequestSuspension(HLERequestContext& ctx) {
LOG_INFO(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(request_suspension_event->GetReadableEvent());
}
void IsPlayTimerAlarmDisabled(HLERequestContext& ctx) {
const bool is_play_timer_alarm_disabled = false;
LOG_INFO(Service_PCTL, "called, is_play_timer_alarm_disabled={}",
is_play_timer_alarm_disabled);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(is_play_timer_alarm_disabled);
}
void GetUnlinkedEvent(HLERequestContext& ctx) {
LOG_INFO(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
rb.PushCopyObjects(unlinked_event->GetReadableEvent());
}
void SetStereoVisionRestriction(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_use = rp.Pop<bool>();
@@ -328,7 +430,7 @@ private:
}
rb.Push(ResultSuccess);
rb.Push(settings.is_stero_vision_restricted);
rb.Push(restriction_settings.is_stero_vision_restricted);
}
void ResetConfirmedStereoVisionPermission(HLERequestContext& ctx) {
@@ -358,16 +460,30 @@ private:
bool stereo_vision{};
};
struct ParentalControlSettings {
// This is nn::pctl::RestrictionSettings
struct RestrictionSettings {
bool is_stero_vision_restricted{};
bool is_free_communication_default_on{};
bool disabled{};
};
static_assert(sizeof(RestrictionSettings) == 0x3, "RestrictionSettings has incorrect size.");
// This is nn::pctl::PlayTimerSettings
struct PlayTimerSettings {
// TODO: RE the actual contents of this struct
std::array<u8, 0x34> settings;
};
static_assert(sizeof(PlayTimerSettings) == 0x34, "PlayTimerSettings has incorrect size.");
States states{};
ParentalControlSettings settings{};
RestrictionSettings restriction_settings{};
std::array<char, 8> pin_code{};
Capability capability{};
Kernel::KEvent* synchronization_event;
Kernel::KEvent* unlinked_event;
Kernel::KEvent* request_suspension_event;
KernelHelpers::ServiceContext service_context;
};
void Module::Interface::CreateService(HLERequestContext& ctx) {

View File

@@ -11,66 +11,6 @@
namespace Service::Set {
namespace {
constexpr std::array<LanguageCode, 18> available_language_codes = {{
LanguageCode::JA,
LanguageCode::EN_US,
LanguageCode::FR,
LanguageCode::DE,
LanguageCode::IT,
LanguageCode::ES,
LanguageCode::ZH_CN,
LanguageCode::KO,
LanguageCode::NL,
LanguageCode::PT,
LanguageCode::RU,
LanguageCode::ZH_TW,
LanguageCode::EN_GB,
LanguageCode::FR_CA,
LanguageCode::ES_419,
LanguageCode::ZH_HANS,
LanguageCode::ZH_HANT,
LanguageCode::PT_BR,
}};
enum class KeyboardLayout : u64 {
Japanese = 0,
EnglishUs = 1,
EnglishUsInternational = 2,
EnglishUk = 3,
French = 4,
FrenchCa = 5,
Spanish = 6,
SpanishLatin = 7,
German = 8,
Italian = 9,
Portuguese = 10,
Russian = 11,
Korean = 12,
ChineseSimplified = 13,
ChineseTraditional = 14,
};
constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_layout{{
{LanguageCode::JA, KeyboardLayout::Japanese},
{LanguageCode::EN_US, KeyboardLayout::EnglishUs},
{LanguageCode::FR, KeyboardLayout::French},
{LanguageCode::DE, KeyboardLayout::German},
{LanguageCode::IT, KeyboardLayout::Italian},
{LanguageCode::ES, KeyboardLayout::Spanish},
{LanguageCode::ZH_CN, KeyboardLayout::ChineseSimplified},
{LanguageCode::KO, KeyboardLayout::Korean},
{LanguageCode::NL, KeyboardLayout::EnglishUsInternational},
{LanguageCode::PT, KeyboardLayout::Portuguese},
{LanguageCode::RU, KeyboardLayout::Russian},
{LanguageCode::ZH_TW, KeyboardLayout::ChineseTraditional},
{LanguageCode::EN_GB, KeyboardLayout::EnglishUk},
{LanguageCode::FR_CA, KeyboardLayout::FrenchCa},
{LanguageCode::ES_419, KeyboardLayout::SpanishLatin},
{LanguageCode::ZH_HANS, KeyboardLayout::ChineseSimplified},
{LanguageCode::ZH_HANT, KeyboardLayout::ChineseTraditional},
{LanguageCode::PT_BR, KeyboardLayout::Portuguese},
}};
constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF;
constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40;

View File

@@ -32,6 +32,67 @@ enum class LanguageCode : u64 {
ZH_HANT = 0x00746E61482D687A,
PT_BR = 0x00000052422D7470,
};
enum class KeyboardLayout : u64 {
Japanese = 0,
EnglishUs = 1,
EnglishUsInternational = 2,
EnglishUk = 3,
French = 4,
FrenchCa = 5,
Spanish = 6,
SpanishLatin = 7,
German = 8,
Italian = 9,
Portuguese = 10,
Russian = 11,
Korean = 12,
ChineseSimplified = 13,
ChineseTraditional = 14,
};
constexpr std::array<LanguageCode, 18> available_language_codes = {{
LanguageCode::JA,
LanguageCode::EN_US,
LanguageCode::FR,
LanguageCode::DE,
LanguageCode::IT,
LanguageCode::ES,
LanguageCode::ZH_CN,
LanguageCode::KO,
LanguageCode::NL,
LanguageCode::PT,
LanguageCode::RU,
LanguageCode::ZH_TW,
LanguageCode::EN_GB,
LanguageCode::FR_CA,
LanguageCode::ES_419,
LanguageCode::ZH_HANS,
LanguageCode::ZH_HANT,
LanguageCode::PT_BR,
}};
static constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_layout{{
{LanguageCode::JA, KeyboardLayout::Japanese},
{LanguageCode::EN_US, KeyboardLayout::EnglishUs},
{LanguageCode::FR, KeyboardLayout::French},
{LanguageCode::DE, KeyboardLayout::German},
{LanguageCode::IT, KeyboardLayout::Italian},
{LanguageCode::ES, KeyboardLayout::Spanish},
{LanguageCode::ZH_CN, KeyboardLayout::ChineseSimplified},
{LanguageCode::KO, KeyboardLayout::Korean},
{LanguageCode::NL, KeyboardLayout::EnglishUsInternational},
{LanguageCode::PT, KeyboardLayout::Portuguese},
{LanguageCode::RU, KeyboardLayout::Russian},
{LanguageCode::ZH_TW, KeyboardLayout::ChineseTraditional},
{LanguageCode::EN_GB, KeyboardLayout::EnglishUk},
{LanguageCode::FR_CA, KeyboardLayout::FrenchCa},
{LanguageCode::ES_419, KeyboardLayout::SpanishLatin},
{LanguageCode::ZH_HANS, KeyboardLayout::ChineseSimplified},
{LanguageCode::ZH_HANT, KeyboardLayout::ChineseTraditional},
{LanguageCode::PT_BR, KeyboardLayout::Portuguese},
}};
LanguageCode GetLanguageCodeFromIndex(std::size_t idx);
class SET final : public ServiceFramework<SET> {

View File

@@ -4,10 +4,12 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "common/string_util.h"
#include "core/file_sys/errors.h"
#include "core/file_sys/system_archive/system_version.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/set/set.h"
#include "core/hle/service/set/set_sys.h"
namespace Service::Set {
@@ -73,6 +75,16 @@ void GetFirmwareVersionImpl(HLERequestContext& ctx, GetFirmwareVersionType type)
}
} // Anonymous namespace
void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
language_code_setting = rp.PopEnum<LanguageCode>();
LOG_INFO(Service_SET, "called, language_code={}", language_code_setting);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version1);
@@ -83,21 +95,113 @@ void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) {
GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version2);
}
void SET_SYS::GetAccountSettings(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushRaw(account_settings);
}
void SET_SYS::SetAccountSettings(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
account_settings = rp.PopRaw<AccountSettings>();
LOG_INFO(Service_SET, "called, account_settings_flags={}", account_settings.flags);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetEulaVersions(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called");
ctx.WriteBuffer(eula_versions);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(static_cast<u32>(eula_versions.size()));
}
void SET_SYS::SetEulaVersions(HLERequestContext& ctx) {
const auto elements = ctx.GetReadBufferNumElements<EulaVersion>();
const auto buffer_data = ctx.ReadBuffer();
LOG_INFO(Service_SET, "called, elements={}", elements);
eula_versions.resize(elements);
for (std::size_t index = 0; index < elements; index++) {
const std::size_t start_index = index * sizeof(EulaVersion);
memcpy(eula_versions.data() + start_index, buffer_data.data() + start_index,
sizeof(EulaVersion));
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetColorSetId(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(color_set);
}
void SET_SYS::SetColorSetId(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
IPC::RequestParser rp{ctx};
color_set = rp.PopEnum<ColorSet>();
LOG_DEBUG(Service_SET, "called, color_set={}", color_set);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetNotificationSettings(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called");
IPC::ResponseBuilder rb{ctx, 8};
rb.Push(ResultSuccess);
rb.PushRaw(notification_settings);
}
void SET_SYS::SetNotificationSettings(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
notification_settings = rp.PopRaw<NotificationSettings>();
LOG_INFO(Service_SET, "called, flags={}, volume={}, head_time={}:{}, tailt_time={}:{}",
notification_settings.flags.raw, notification_settings.volume,
notification_settings.start_time.hour, notification_settings.start_time.minute,
notification_settings.stop_time.hour, notification_settings.stop_time.minute);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetAccountNotificationSettings(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called");
ctx.WriteBuffer(account_notifications);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(static_cast<u32>(account_notifications.size()));
}
void SET_SYS::SetAccountNotificationSettings(HLERequestContext& ctx) {
const auto elements = ctx.GetReadBufferNumElements<AccountNotificationSettings>();
const auto buffer_data = ctx.ReadBuffer();
LOG_INFO(Service_SET, "called, elements={}", elements);
account_notifications.resize(elements);
for (std::size_t index = 0; index < elements; index++) {
const std::size_t start_index = index * sizeof(AccountNotificationSettings);
memcpy(account_notifications.data() + start_index, buffer_data.data() + start_index,
sizeof(AccountNotificationSettings));
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@@ -177,17 +281,218 @@ void SET_SYS::GetSettingsItemValue(HLERequestContext& ctx) {
rb.Push(response);
}
void SET_SYS::GetDeviceNickName(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
void SET_SYS::GetTvSettings(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called");
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(ResultSuccess);
rb.PushRaw(tv_settings);
}
void SET_SYS::SetTvSettings(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
tv_settings = rp.PopRaw<TvSettings>();
LOG_INFO(Service_SET,
"called, flags={}, cmu_mode={}, constrast_ratio={}, hdmi_content_type={}, "
"rgb_range={}, tv_gama={}, tv_resolution={}, tv_underscan={}",
tv_settings.flags.raw, tv_settings.cmu_mode, tv_settings.constrast_ratio,
tv_settings.hdmi_content_type, tv_settings.rgb_range, tv_settings.tv_gama,
tv_settings.tv_resolution, tv_settings.tv_underscan);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetQuestFlag(HLERequestContext& ctx) {
LOG_WARNING(Service_SET, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(QuestFlag::Retail);
}
void SET_SYS::SetRegionCode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
region_code = rp.PopEnum<RegionCode>();
LOG_INFO(Service_SET, "called, region_code={}", region_code);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetPrimaryAlbumStorage(HLERequestContext& ctx) {
LOG_WARNING(Service_SET, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(PrimaryAlbumStorage::SdCard);
}
void SET_SYS::GetSleepSettings(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called");
IPC::ResponseBuilder rb{ctx, 5};
rb.Push(ResultSuccess);
rb.PushRaw(sleep_settings);
}
void SET_SYS::SetSleepSettings(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
sleep_settings = rp.PopRaw<SleepSettings>();
LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}",
sleep_settings.flags.raw, sleep_settings.handheld_sleep_plan,
sleep_settings.console_sleep_plan);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetInitialLaunchSettings(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called");
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(ResultSuccess);
rb.PushRaw(launch_settings);
}
void SET_SYS::SetInitialLaunchSettings(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
launch_settings = rp.PopRaw<InitialLaunchSettings>();
LOG_INFO(Service_SET, "called, flags={}, timestamp={}", launch_settings.flags.raw,
launch_settings.timestamp.time_point);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetDeviceNickName(HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
ctx.WriteBuffer(::Settings::values.device_name.GetValue());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::SetDeviceNickName(HLERequestContext& ctx) {
const std::string device_name = Common::StringFromBuffer(ctx.ReadBuffer());
LOG_INFO(Service_SET, "called, device_name={}", device_name);
::Settings::values.device_name = device_name;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetProductModel(HLERequestContext& ctx) {
const u32 product_model = 1;
LOG_WARNING(Service_SET, "(STUBBED) called, product_model={}", product_model);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(product_model);
}
void SET_SYS::GetMiiAuthorId(HLERequestContext& ctx) {
const auto author_id = Common::UUID::MakeDefault();
LOG_WARNING(Service_SET, "(STUBBED) called, author_id={}", author_id.FormattedString());
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
rb.PushRaw(author_id);
}
void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) {
u8 auto_update_flag{};
LOG_WARNING(Service_SET, "(STUBBED) called, auto_update_flag={}", auto_update_flag);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(auto_update_flag);
}
void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) {
u8 battery_percentage_flag{1};
LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}",
battery_percentage_flag);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(battery_percentage_flag);
}
void SET_SYS::GetErrorReportSharePermission(HLERequestContext& ctx) {
LOG_WARNING(Service_SET, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(ErrorReportSharePermission::Denied);
}
void SET_SYS::GetAppletLaunchFlags(HLERequestContext& ctx) {
LOG_INFO(Service_SET, "called, applet_launch_flag={}", applet_launch_flag);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(applet_launch_flag);
}
void SET_SYS::SetAppletLaunchFlags(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
applet_launch_flag = rp.Pop<u32>();
LOG_INFO(Service_SET, "called, applet_launch_flag={}", applet_launch_flag);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void SET_SYS::GetKeyboardLayout(HLERequestContext& ctx) {
const auto language_code =
available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())];
const auto key_code =
std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
[=](const auto& element) { return element.first == language_code; });
KeyboardLayout selected_keyboard_layout = KeyboardLayout::EnglishUs;
if (key_code != language_to_layout.end()) {
selected_keyboard_layout = key_code->second;
}
LOG_INFO(Service_SET, "called, selected_keyboard_layout={}", selected_keyboard_layout);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(static_cast<u32>(selected_keyboard_layout));
}
void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) {
LOG_WARNING(Service_SET, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(ChineseTraditionalInputMethod::Unknown0);
}
void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) {
LOG_WARNING(Service_SET, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(false);
}
SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "SetLanguageCode"},
{0, &SET_SYS::SetLanguageCode, "SetLanguageCode"},
{1, nullptr, "SetNetworkSettings"},
{2, nullptr, "GetNetworkSettings"},
{3, &SET_SYS::GetFirmwareVersion, "GetFirmwareVersion"},
@@ -203,35 +508,35 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{14, nullptr, "SetExternalSteadyClockSourceId"},
{15, nullptr, "GetUserSystemClockContext"},
{16, nullptr, "SetUserSystemClockContext"},
{17, nullptr, "GetAccountSettings"},
{18, nullptr, "SetAccountSettings"},
{17, &SET_SYS::GetAccountSettings, "GetAccountSettings"},
{18, &SET_SYS::SetAccountSettings, "SetAccountSettings"},
{19, nullptr, "GetAudioVolume"},
{20, nullptr, "SetAudioVolume"},
{21, nullptr, "GetEulaVersions"},
{22, nullptr, "SetEulaVersions"},
{21, &SET_SYS::GetEulaVersions, "GetEulaVersions"},
{22, &SET_SYS::SetEulaVersions, "SetEulaVersions"},
{23, &SET_SYS::GetColorSetId, "GetColorSetId"},
{24, &SET_SYS::SetColorSetId, "SetColorSetId"},
{25, nullptr, "GetConsoleInformationUploadFlag"},
{26, nullptr, "SetConsoleInformationUploadFlag"},
{27, nullptr, "GetAutomaticApplicationDownloadFlag"},
{28, nullptr, "SetAutomaticApplicationDownloadFlag"},
{29, nullptr, "GetNotificationSettings"},
{30, nullptr, "SetNotificationSettings"},
{31, nullptr, "GetAccountNotificationSettings"},
{32, nullptr, "SetAccountNotificationSettings"},
{29, &SET_SYS::GetNotificationSettings, "GetNotificationSettings"},
{30, &SET_SYS::SetNotificationSettings, "SetNotificationSettings"},
{31, &SET_SYS::GetAccountNotificationSettings, "GetAccountNotificationSettings"},
{32, &SET_SYS::SetAccountNotificationSettings, "SetAccountNotificationSettings"},
{35, nullptr, "GetVibrationMasterVolume"},
{36, nullptr, "SetVibrationMasterVolume"},
{37, &SET_SYS::GetSettingsItemValueSize, "GetSettingsItemValueSize"},
{38, &SET_SYS::GetSettingsItemValue, "GetSettingsItemValue"},
{39, nullptr, "GetTvSettings"},
{40, nullptr, "SetTvSettings"},
{39, &SET_SYS::GetTvSettings, "GetTvSettings"},
{40, &SET_SYS::SetTvSettings, "SetTvSettings"},
{41, nullptr, "GetEdid"},
{42, nullptr, "SetEdid"},
{43, nullptr, "GetAudioOutputMode"},
{44, nullptr, "SetAudioOutputMode"},
{45, nullptr, "IsForceMuteOnHeadphoneRemoved"},
{46, nullptr, "SetForceMuteOnHeadphoneRemoved"},
{47, nullptr, "GetQuestFlag"},
{47, &SET_SYS::GetQuestFlag, "GetQuestFlag"},
{48, nullptr, "SetQuestFlag"},
{49, nullptr, "GetDataDeletionSettings"},
{50, nullptr, "SetDataDeletionSettings"},
@@ -241,13 +546,13 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{54, nullptr, "SetDeviceTimeZoneLocationName"},
{55, nullptr, "GetWirelessCertificationFileSize"},
{56, nullptr, "GetWirelessCertificationFile"},
{57, nullptr, "SetRegionCode"},
{57, &SET_SYS::SetRegionCode, "SetRegionCode"},
{58, nullptr, "GetNetworkSystemClockContext"},
{59, nullptr, "SetNetworkSystemClockContext"},
{60, nullptr, "IsUserSystemClockAutomaticCorrectionEnabled"},
{61, nullptr, "SetUserSystemClockAutomaticCorrectionEnabled"},
{62, nullptr, "GetDebugModeFlag"},
{63, nullptr, "GetPrimaryAlbumStorage"},
{63, &SET_SYS::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"},
{64, nullptr, "SetPrimaryAlbumStorage"},
{65, nullptr, "GetUsb30EnableFlag"},
{66, nullptr, "SetUsb30EnableFlag"},
@@ -255,15 +560,15 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{68, nullptr, "GetSerialNumber"},
{69, nullptr, "GetNfcEnableFlag"},
{70, nullptr, "SetNfcEnableFlag"},
{71, nullptr, "GetSleepSettings"},
{72, nullptr, "SetSleepSettings"},
{71, &SET_SYS::GetSleepSettings, "GetSleepSettings"},
{72, &SET_SYS::SetSleepSettings, "SetSleepSettings"},
{73, nullptr, "GetWirelessLanEnableFlag"},
{74, nullptr, "SetWirelessLanEnableFlag"},
{75, nullptr, "GetInitialLaunchSettings"},
{76, nullptr, "SetInitialLaunchSettings"},
{75, &SET_SYS::GetInitialLaunchSettings, "GetInitialLaunchSettings"},
{76, &SET_SYS::SetInitialLaunchSettings, "SetInitialLaunchSettings"},
{77, &SET_SYS::GetDeviceNickName, "GetDeviceNickName"},
{78, nullptr, "SetDeviceNickName"},
{79, nullptr, "GetProductModel"},
{78, &SET_SYS::SetDeviceNickName, "SetDeviceNickName"},
{79, &SET_SYS::GetProductModel, "GetProductModel"},
{80, nullptr, "GetLdnChannel"},
{81, nullptr, "SetLdnChannel"},
{82, nullptr, "AcquireTelemetryDirtyFlagEventHandle"},
@@ -274,16 +579,16 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{87, nullptr, "SetPtmFuelGaugeParameter"},
{88, nullptr, "GetBluetoothEnableFlag"},
{89, nullptr, "SetBluetoothEnableFlag"},
{90, nullptr, "GetMiiAuthorId"},
{90, &SET_SYS::GetMiiAuthorId, "GetMiiAuthorId"},
{91, nullptr, "SetShutdownRtcValue"},
{92, nullptr, "GetShutdownRtcValue"},
{93, nullptr, "AcquireFatalDirtyFlagEventHandle"},
{94, nullptr, "GetFatalDirtyFlags"},
{95, nullptr, "GetAutoUpdateEnableFlag"},
{95, &SET_SYS::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"},
{96, nullptr, "SetAutoUpdateEnableFlag"},
{97, nullptr, "GetNxControllerSettings"},
{98, nullptr, "SetNxControllerSettings"},
{99, nullptr, "GetBatteryPercentageFlag"},
{99, &SET_SYS::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"},
{100, nullptr, "SetBatteryPercentageFlag"},
{101, nullptr, "GetExternalRtcResetFlag"},
{102, nullptr, "SetExternalRtcResetFlag"},
@@ -308,10 +613,10 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{121, nullptr, "SetPushNotificationActivityModeOnSleep"},
{122, nullptr, "GetServiceDiscoveryControlSettings"},
{123, nullptr, "SetServiceDiscoveryControlSettings"},
{124, nullptr, "GetErrorReportSharePermission"},
{124, &SET_SYS::GetErrorReportSharePermission, "GetErrorReportSharePermission"},
{125, nullptr, "SetErrorReportSharePermission"},
{126, nullptr, "GetAppletLaunchFlags"},
{127, nullptr, "SetAppletLaunchFlags"},
{126, &SET_SYS::GetAppletLaunchFlags, "GetAppletLaunchFlags"},
{127, &SET_SYS::SetAppletLaunchFlags, "SetAppletLaunchFlags"},
{128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"},
{129, nullptr, "SetConsoleSixAxisSensorAccelerationBias"},
{130, nullptr, "GetConsoleSixAxisSensorAngularVelocityBias"},
@@ -320,7 +625,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{133, nullptr, "SetConsoleSixAxisSensorAccelerationGain"},
{134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"},
{135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"},
{136, nullptr, "GetKeyboardLayout"},
{136, &SET_SYS::GetKeyboardLayout, "GetKeyboardLayout"},
{137, nullptr, "SetKeyboardLayout"},
{138, nullptr, "GetWebInspectorFlag"},
{139, nullptr, "GetAllowedSslHosts"},
@@ -354,7 +659,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{167, nullptr, "SetUsb30DeviceEnableFlag"},
{168, nullptr, "GetThemeId"},
{169, nullptr, "SetThemeId"},
{170, nullptr, "GetChineseTraditionalInputMethod"},
{170, &SET_SYS::GetChineseTraditionalInputMethod, "GetChineseTraditionalInputMethod"},
{171, nullptr, "SetChineseTraditionalInputMethod"},
{172, nullptr, "GetPtmCycleCountReliability"},
{173, nullptr, "SetPtmCycleCountReliability"},
@@ -385,12 +690,16 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{198, nullptr, "SetButtonConfigRegisteredSettingsEmbedded"},
{199, nullptr, "GetButtonConfigRegisteredSettings"},
{200, nullptr, "SetButtonConfigRegisteredSettings"},
{201, nullptr, "GetFieldTestingFlag"},
{201, &SET_SYS::GetFieldTestingFlag, "GetFieldTestingFlag"},
{202, nullptr, "SetFieldTestingFlag"},
{203, nullptr, "GetPanelCrcMode"},
{204, nullptr, "SetPanelCrcMode"},
{205, nullptr, "GetNxControllerSettingsEx"},
{206, nullptr, "SetNxControllerSettingsEx"},
{207, nullptr, "GetHearingProtectionSafeguardFlag"},
{208, nullptr, "SetHearingProtectionSafeguardFlag"},
{209, nullptr, "GetHearingProtectionSafeguardRemainingTime"},
{210, nullptr, "SetHearingProtectionSafeguardRemainingTime"},
};
// clang-format on

View File

@@ -3,7 +3,9 @@
#pragma once
#include "common/uuid.h"
#include "core/hle/service/service.h"
#include "core/hle/service/time/clock_types.h"
namespace Core {
class System;
@@ -23,15 +25,331 @@ private:
BasicBlack = 1,
};
void GetSettingsItemValueSize(HLERequestContext& ctx);
void GetSettingsItemValue(HLERequestContext& ctx);
/// Indicates the current console is a retail or kiosk unit
enum class QuestFlag : u8 {
Retail = 0,
Kiosk = 1,
};
/// This is nn::settings::system::TvResolution
enum class TvResolution : u32 {
Auto,
Resolution1080p,
Resolution720p,
Resolution480p,
};
/// This is nn::settings::system::HdmiContentType
enum class HdmiContentType : u32 {
None,
Graphics,
Cinema,
Photo,
Game,
};
/// This is nn::settings::system::RgbRange
enum class RgbRange : u32 {
Auto,
Full,
Limited,
};
/// This is nn::settings::system::CmuMode
enum class CmuMode : u32 {
None,
ColorInvert,
HighContrast,
GrayScale,
};
/// This is nn::settings::system::PrimaryAlbumStorage
enum class PrimaryAlbumStorage : u32 {
Nand,
SdCard,
};
/// This is nn::settings::system::NotificationVolume
enum class NotificationVolume : u32 {
Mute,
Low,
High,
};
/// This is nn::settings::system::ChineseTraditionalInputMethod
enum class ChineseTraditionalInputMethod : u32 {
Unknown0 = 0,
Unknown1 = 1,
Unknown2 = 2,
};
/// This is nn::settings::system::ErrorReportSharePermission
enum class ErrorReportSharePermission : u32 {
NotConfirmed,
Granted,
Denied,
};
/// This is nn::settings::system::FriendPresenceOverlayPermission
enum class FriendPresenceOverlayPermission : u8 {
NotConfirmed,
NoDisplay,
FavoriteFriends,
Friends,
};
/// This is nn::settings::system::HandheldSleepPlan
enum class HandheldSleepPlan : u32 {
Sleep1Min,
Sleep3Min,
Sleep5Min,
Sleep10Min,
Sleep30Min,
Never,
};
/// This is nn::settings::system::ConsoleSleepPlan
enum class ConsoleSleepPlan : u32 {
Sleep1Hour,
Sleep2Hour,
Sleep3Hour,
Sleep6Hour,
Sleep12Hour,
Never,
};
/// This is nn::settings::system::RegionCode
enum class RegionCode : u32 {
Japan,
Usa,
Europe,
Australia,
HongKongTaiwanKorea,
China,
};
/// This is nn::settings::system::EulaVersionClockType
enum class EulaVersionClockType : u32 {
NetworkSystemClock,
SteadyClock,
};
/// This is nn::settings::system::SleepFlag
struct SleepFlag {
union {
u32 raw{};
BitField<0, 1, u32> SleepsWhilePlayingMedia;
BitField<1, 1, u32> WakesAtPowerStateChange;
};
};
static_assert(sizeof(SleepFlag) == 4, "TvFlag is an invalid size");
/// This is nn::settings::system::TvFlag
struct TvFlag {
union {
u32 raw{};
BitField<0, 1, u32> Allows4k;
BitField<1, 1, u32> Allows3d;
BitField<2, 1, u32> AllowsCec;
BitField<3, 1, u32> PreventsScreenBurnIn;
};
};
static_assert(sizeof(TvFlag) == 4, "TvFlag is an invalid size");
/// This is nn::settings::system::InitialLaunchFlag
struct InitialLaunchFlag {
union {
u32 raw{};
BitField<0, 1, u32> InitialLaunchCompletionFlag;
BitField<8, 1, u32> InitialLaunchUserAdditionFlag;
BitField<16, 1, u32> InitialLaunchTimestampFlag;
};
};
static_assert(sizeof(InitialLaunchFlag) == 4, "InitialLaunchFlag is an invalid size");
/// This is nn::settings::system::NotificationFlag
struct NotificationFlag {
union {
u32 raw{};
BitField<0, 1, u32> RingtoneFlag;
BitField<1, 1, u32> DownloadCompletionFlag;
BitField<8, 1, u32> EnablesNews;
BitField<9, 1, u32> IncomingLampFlag;
};
};
static_assert(sizeof(NotificationFlag) == 4, "NotificationFlag is an invalid size");
/// This is nn::settings::system::AccountNotificationFlag
struct AccountNotificationFlag {
union {
u32 raw{};
BitField<0, 1, u32> FriendOnlineFlag;
BitField<1, 1, u32> FriendRequestFlag;
BitField<8, 1, u32> CoralInvitationFlag;
};
};
static_assert(sizeof(AccountNotificationFlag) == 4,
"AccountNotificationFlag is an invalid size");
/// This is nn::settings::system::TvSettings
struct TvSettings {
TvFlag flags;
TvResolution tv_resolution;
HdmiContentType hdmi_content_type;
RgbRange rgb_range;
CmuMode cmu_mode;
u32 tv_underscan;
f32 tv_gama;
f32 constrast_ratio;
};
static_assert(sizeof(TvSettings) == 0x20, "TvSettings is an invalid size");
/// This is nn::settings::system::NotificationTime
struct NotificationTime {
u32 hour;
u32 minute;
};
static_assert(sizeof(NotificationTime) == 0x8, "NotificationTime is an invalid size");
/// This is nn::settings::system::NotificationSettings
struct NotificationSettings {
NotificationFlag flags;
NotificationVolume volume;
NotificationTime start_time;
NotificationTime stop_time;
};
static_assert(sizeof(NotificationSettings) == 0x18, "NotificationSettings is an invalid size");
/// This is nn::settings::system::AccountSettings
struct AccountSettings {
u32 flags;
};
static_assert(sizeof(AccountSettings) == 0x4, "AccountSettings is an invalid size");
/// This is nn::settings::system::AccountNotificationSettings
struct AccountNotificationSettings {
Common::UUID uid;
AccountNotificationFlag flags;
FriendPresenceOverlayPermission friend_presence_permission;
FriendPresenceOverlayPermission friend_invitation_permission;
INSERT_PADDING_BYTES(0x2);
};
static_assert(sizeof(AccountNotificationSettings) == 0x18,
"AccountNotificationSettings is an invalid size");
/// This is nn::settings::system::InitialLaunchSettings
struct SleepSettings {
SleepFlag flags;
HandheldSleepPlan handheld_sleep_plan;
ConsoleSleepPlan console_sleep_plan;
};
static_assert(sizeof(SleepSettings) == 0xc, "SleepSettings is incorrect size");
/// This is nn::settings::system::InitialLaunchSettings
struct InitialLaunchSettings {
InitialLaunchFlag flags;
INSERT_PADDING_BYTES(0x4);
Time::Clock::SteadyClockTimePoint timestamp;
};
static_assert(sizeof(InitialLaunchSettings) == 0x20, "InitialLaunchSettings is incorrect size");
/// This is nn::settings::system::InitialLaunchSettings
struct EulaVersion {
u32 version;
RegionCode region_code;
EulaVersionClockType clock_type;
INSERT_PADDING_BYTES(0x4);
s64 posix_time;
Time::Clock::SteadyClockTimePoint timestamp;
};
static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size");
void SetLanguageCode(HLERequestContext& ctx);
void GetFirmwareVersion(HLERequestContext& ctx);
void GetFirmwareVersion2(HLERequestContext& ctx);
void GetAccountSettings(HLERequestContext& ctx);
void SetAccountSettings(HLERequestContext& ctx);
void GetEulaVersions(HLERequestContext& ctx);
void SetEulaVersions(HLERequestContext& ctx);
void GetColorSetId(HLERequestContext& ctx);
void SetColorSetId(HLERequestContext& ctx);
void GetNotificationSettings(HLERequestContext& ctx);
void SetNotificationSettings(HLERequestContext& ctx);
void GetAccountNotificationSettings(HLERequestContext& ctx);
void SetAccountNotificationSettings(HLERequestContext& ctx);
void GetSettingsItemValueSize(HLERequestContext& ctx);
void GetSettingsItemValue(HLERequestContext& ctx);
void GetTvSettings(HLERequestContext& ctx);
void SetTvSettings(HLERequestContext& ctx);
void GetQuestFlag(HLERequestContext& ctx);
void SetRegionCode(HLERequestContext& ctx);
void GetPrimaryAlbumStorage(HLERequestContext& ctx);
void GetSleepSettings(HLERequestContext& ctx);
void SetSleepSettings(HLERequestContext& ctx);
void GetInitialLaunchSettings(HLERequestContext& ctx);
void SetInitialLaunchSettings(HLERequestContext& ctx);
void GetDeviceNickName(HLERequestContext& ctx);
void SetDeviceNickName(HLERequestContext& ctx);
void GetProductModel(HLERequestContext& ctx);
void GetMiiAuthorId(HLERequestContext& ctx);
void GetAutoUpdateEnableFlag(HLERequestContext& ctx);
void GetBatteryPercentageFlag(HLERequestContext& ctx);
void GetErrorReportSharePermission(HLERequestContext& ctx);
void GetAppletLaunchFlags(HLERequestContext& ctx);
void SetAppletLaunchFlags(HLERequestContext& ctx);
void GetKeyboardLayout(HLERequestContext& ctx);
void GetChineseTraditionalInputMethod(HLERequestContext& ctx);
void GetFieldTestingFlag(HLERequestContext& ctx);
AccountSettings account_settings{
.flags = {},
};
ColorSet color_set = ColorSet::BasicWhite;
NotificationSettings notification_settings{
.flags = {0x300},
.volume = NotificationVolume::High,
.start_time = {.hour = 9, .minute = 0},
.stop_time = {.hour = 21, .minute = 0},
};
std::vector<AccountNotificationSettings> account_notifications{};
TvSettings tv_settings{
.flags = {0xc},
.tv_resolution = TvResolution::Auto,
.hdmi_content_type = HdmiContentType::Game,
.rgb_range = RgbRange::Auto,
.cmu_mode = CmuMode::None,
.tv_underscan = {},
.tv_gama = 1.0f,
.constrast_ratio = 0.5f,
};
InitialLaunchSettings launch_settings{
.flags = {0x10001},
.timestamp = {},
};
SleepSettings sleep_settings{
.flags = {0x3},
.handheld_sleep_plan = HandheldSleepPlan::Sleep10Min,
.console_sleep_plan = ConsoleSleepPlan::Sleep1Hour,
};
u32 applet_launch_flag{};
std::vector<EulaVersion> eula_versions{};
RegionCode region_code;
LanguageCode language_code_setting;
};
} // namespace Service::Set

View File

@@ -509,9 +509,9 @@ class GuestMemory {
public:
GuestMemory() = delete;
explicit GuestMemory(M& memory_, u64 addr_, std::size_t size_,
explicit GuestMemory(M& memory, u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr)
: memory{memory_}, addr{addr_}, size{size_} {
: m_memory{memory}, m_addr{addr}, m_size{size} {
static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write);
if constexpr (FLAGS & GuestMemoryFlags::Read) {
Read(addr, size, backup);
@@ -521,89 +521,97 @@ public:
~GuestMemory() = default;
T* data() noexcept {
return data_span.data();
return m_data_span.data();
}
const T* data() const noexcept {
return data_span.data();
return m_data_span.data();
}
size_t size() const noexcept {
return m_size;
}
size_t size_bytes() const noexcept {
return this->size() * sizeof(T);
}
[[nodiscard]] T* begin() noexcept {
return data();
return this->data();
}
[[nodiscard]] const T* begin() const noexcept {
return data();
return this->data();
}
[[nodiscard]] T* end() noexcept {
return data() + size;
return this->data() + this->size();
}
[[nodiscard]] const T* end() const noexcept {
return data() + size;
return this->data() + this->size();
}
T& operator[](size_t index) noexcept {
return data_span[index];
return m_data_span[index];
}
const T& operator[](size_t index) const noexcept {
return data_span[index];
return m_data_span[index];
}
void SetAddressAndSize(u64 addr_, std::size_t size_) noexcept {
addr = addr_;
size = size_;
addr_changed = true;
void SetAddressAndSize(u64 addr, std::size_t size) noexcept {
m_addr = addr;
m_size = size;
m_addr_changed = true;
}
std::span<T> Read(u64 addr_, std::size_t size_,
std::span<T> Read(u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr) noexcept {
addr = addr_;
size = size_;
if (size == 0) {
is_data_copy = true;
m_addr = addr;
m_size = size;
if (m_size == 0) {
m_is_data_copy = true;
return {};
}
if (TrySetSpan()) {
if (this->TrySetSpan()) {
if constexpr (FLAGS & GuestMemoryFlags::Safe) {
memory.FlushRegion(addr, size * sizeof(T));
m_memory.FlushRegion(m_addr, this->size_bytes());
}
} else {
if (backup) {
backup->resize_destructive(size);
data_span = *backup;
backup->resize_destructive(this->size());
m_data_span = *backup;
} else {
data_copy.resize(size);
data_span = std::span(data_copy);
m_data_copy.resize(this->size());
m_data_span = std::span(m_data_copy);
}
is_data_copy = true;
span_valid = true;
m_is_data_copy = true;
m_span_valid = true;
if constexpr (FLAGS & GuestMemoryFlags::Safe) {
memory.ReadBlock(addr, data_span.data(), size * sizeof(T));
m_memory.ReadBlock(m_addr, this->data(), this->size_bytes());
} else {
memory.ReadBlockUnsafe(addr, data_span.data(), size * sizeof(T));
m_memory.ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
}
}
return data_span;
return m_data_span;
}
void Write(std::span<T> write_data) noexcept {
if constexpr (FLAGS & GuestMemoryFlags::Cached) {
memory.WriteBlockCached(addr, write_data.data(), size * sizeof(T));
m_memory.WriteBlockCached(m_addr, write_data.data(), this->size_bytes());
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
memory.WriteBlock(addr, write_data.data(), size * sizeof(T));
m_memory.WriteBlock(m_addr, write_data.data(), this->size_bytes());
} else {
memory.WriteBlockUnsafe(addr, write_data.data(), size * sizeof(T));
m_memory.WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes());
}
}
bool TrySetSpan() noexcept {
if (u8* ptr = memory.GetSpan(addr, size * sizeof(T)); ptr) {
data_span = {reinterpret_cast<T*>(ptr), size};
span_valid = true;
if (u8* ptr = m_memory.GetSpan(m_addr, this->size_bytes()); ptr) {
m_data_span = {reinterpret_cast<T*>(ptr), this->size()};
m_span_valid = true;
return true;
}
return false;
@@ -611,36 +619,36 @@ public:
protected:
bool IsDataCopy() const noexcept {
return is_data_copy;
return m_is_data_copy;
}
bool AddressChanged() const noexcept {
return addr_changed;
return m_addr_changed;
}
M& memory;
u64 addr;
size_t size;
std::span<T> data_span{};
std::vector<T> data_copy;
bool span_valid{false};
bool is_data_copy{false};
bool addr_changed{false};
M& m_memory;
u64 m_addr{};
size_t m_size{};
std::span<T> m_data_span{};
std::vector<T> m_data_copy{};
bool m_span_valid{false};
bool m_is_data_copy{false};
bool m_addr_changed{false};
};
template <typename M, typename T, GuestMemoryFlags FLAGS>
class GuestMemoryScoped : public GuestMemory<M, T, FLAGS> {
public:
GuestMemoryScoped() = delete;
explicit GuestMemoryScoped(M& memory_, u64 addr_, std::size_t size_,
explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr)
: GuestMemory<M, T, FLAGS>(memory_, addr_, size_, backup) {
: GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {
if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
if (!this->TrySetSpan()) {
if (backup) {
this->data_span = *backup;
this->span_valid = true;
this->is_data_copy = true;
this->m_data_span = *backup;
this->m_span_valid = true;
this->m_is_data_copy = true;
}
}
}
@@ -648,24 +656,21 @@ public:
~GuestMemoryScoped() {
if constexpr (FLAGS & GuestMemoryFlags::Write) {
if (this->size == 0) [[unlikely]] {
if (this->size() == 0) [[unlikely]] {
return;
}
if (this->AddressChanged() || this->IsDataCopy()) {
ASSERT(this->span_valid);
ASSERT(this->m_span_valid);
if constexpr (FLAGS & GuestMemoryFlags::Cached) {
this->memory.WriteBlockCached(this->addr, this->data_span.data(),
this->size * sizeof(T));
this->m_memory.WriteBlockCached(this->m_addr, this->data(), this->size_bytes());
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
this->memory.WriteBlock(this->addr, this->data_span.data(),
this->size * sizeof(T));
this->m_memory.WriteBlock(this->m_addr, this->data(), this->size_bytes());
} else {
this->memory.WriteBlockUnsafe(this->addr, this->data_span.data(),
this->size * sizeof(T));
this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes());
}
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
this->memory.InvalidateRegion(this->addr, this->size * sizeof(T));
this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes());
}
}
}

View File

@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/polyfill_ranges.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/memory.h"

View File

@@ -106,6 +106,43 @@ bool IsASTCSupported() {
return true;
}
static bool HasSlowSoftwareAstc(std::string_view vendor_name, std::string_view renderer) {
// ifdef for Unix reduces string comparisons for non-Windows drivers, and Intel
#ifdef YUZU_UNIX
// Sorted vaguely by how likely a vendor is to appear
if (vendor_name == "AMD") {
// RadeonSI
return true;
}
if (vendor_name == "Intel") {
// Must be inside YUZU_UNIX ifdef as the Windows driver uses the same vendor string
// iris, crocus
const bool is_intel_dg = (renderer.find("DG") != std::string_view::npos);
return is_intel_dg;
}
if (vendor_name == "nouveau") {
return true;
}
if (vendor_name == "X.Org") {
// R600
return true;
}
#endif
if (vendor_name == "Collabora Ltd") {
// Zink
return true;
}
if (vendor_name == "Microsoft Corporation") {
// d3d12
return true;
}
if (vendor_name == "Mesa/X.org") {
// llvmpipe, softpipe, virgl
return true;
}
return false;
}
[[nodiscard]] bool IsDebugToolAttached(std::span<const std::string_view> extensions) {
const bool nsight = std::getenv("NVTX_INJECTION64_PATH") || std::getenv("NSIGHT_LAUNCHED");
return nsight || HasExtension(extensions, "GL_EXT_debug_tool") ||
@@ -120,12 +157,16 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
}
vendor_name = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
const std::string_view version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
const std::string_view renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
const std::vector extensions = GetExtensions();
const bool is_nvidia = vendor_name == "NVIDIA Corporation";
const bool is_amd = vendor_name == "ATI Technologies Inc.";
const bool is_intel = vendor_name == "Intel";
const bool has_slow_software_astc =
!is_nvidia && !is_amd && HasSlowSoftwareAstc(vendor_name, renderer);
#ifdef __unix__
constexpr bool is_linux = true;
#else
@@ -152,7 +193,7 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array;
has_image_load_formatted = HasExtension(extensions, "GL_EXT_shader_image_load_formatted");
has_texture_shadow_lod = HasExtension(extensions, "GL_EXT_texture_shadow_lod");
has_astc = IsASTCSupported();
has_astc = !has_slow_software_astc && IsASTCSupported();
has_variable_aoffi = TestVariableAoffi();
has_component_indexing_bug = is_amd;
has_precise_bug = TestPreciseBug();

View File

@@ -963,7 +963,7 @@ bool Device::GetSuitability(bool requires_swapchain) {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
SetNext(next, properties.push_descriptor);
}
if (extensions.subgroup_size_control) {
if (extensions.subgroup_size_control || features.subgroup_size_control.subgroupSizeControl) {
properties.subgroup_size_control.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES;
SetNext(next, properties.subgroup_size_control);

View File

@@ -20,7 +20,6 @@ VK_DEFINE_HANDLE(VmaAllocator)
// Vulkan version in the macro describes the minimum version required for feature availability.
// If the Vulkan version is lower than the required version, the named extension is required.
#define FOR_EACH_VK_FEATURE_1_1(FEATURE) \
FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) \
FEATURE(KHR, 16BitStorage, 16BIT_STORAGE, bit16_storage) \
FEATURE(KHR, ShaderAtomicInt64, SHADER_ATOMIC_INT64, shader_atomic_int64) \
FEATURE(KHR, ShaderDrawParameters, SHADER_DRAW_PARAMETERS, shader_draw_parameters) \
@@ -36,7 +35,8 @@ VK_DEFINE_HANDLE(VmaAllocator)
#define FOR_EACH_VK_FEATURE_1_3(FEATURE) \
FEATURE(EXT, ShaderDemoteToHelperInvocation, SHADER_DEMOTE_TO_HELPER_INVOCATION, \
shader_demote_to_helper_invocation)
shader_demote_to_helper_invocation) \
FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control)
// Define all features which may be used by the implementation and require an extension here.
#define FOR_EACH_VK_FEATURE_EXT(FEATURE) \