summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp10
-rw-r--r--src/core/hle/service/am/am.cpp22
-rw-r--r--src/core/hle/service/am/am.h2
-rw-r--r--src/core/hle/service/hid/hid.cpp13
-rw-r--r--src/core/hle/service/nifm/nifm.cpp165
-rw-r--r--src/core/hle/service/prepo/prepo.cpp21
-rw-r--r--src/core/hle/service/sockets/bsd.cpp18
-rw-r--r--src/core/hle/service/sockets/bsd.h1
8 files changed, 239 insertions, 13 deletions
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp
index d9865d56f..50b2c58e2 100644
--- a/src/core/hle/service/acc/profile_manager.cpp
+++ b/src/core/hle/service/acc/profile_manager.cpp
@@ -41,12 +41,18 @@ constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "/system/save/8000000000000010/su/
ProfileManager::ProfileManager() {
ParseUserSaveFile();
- if (user_count == 0)
+ // Create an user if none are present
+ if (user_count == 0) {
CreateNewUser(UUID::Generate(), "yuzu");
+ }
auto current = std::clamp<int>(Settings::values.current_user, 0, MAX_USERS - 1);
- if (UserExistsIndex(current))
+
+ // If user index don't exist. Load the first user and change the active user
+ if (!UserExistsIndex(current)) {
current = 0;
+ Settings::values.current_user = 0;
+ }
OpenUser(*GetUser(current));
}
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 41bd1497c..d42236a3a 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -1192,7 +1192,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
{50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
{60, nullptr, "SetMediaPlaybackStateForApplication"},
- {65, nullptr, "IsGamePlayRecordingSupported"},
+ {65, &IApplicationFunctions::IsGamePlayRecordingSupported, "IsGamePlayRecordingSupported"},
{66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
{67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
{68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
@@ -1213,7 +1213,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
{130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
{140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"},
- {141, nullptr, "TryPopFromFriendInvitationStorageChannel"},
+ {141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"},
{150, nullptr, "GetNotificationStorageChannelEvent"},
{151, nullptr, "TryPopFromNotificationStorageChannel"},
{160, nullptr, "GetHealthWarningDisappearedSystemEvent"},
@@ -1480,6 +1480,16 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
rb.Push(*res_code);
}
+void IApplicationFunctions::IsGamePlayRecordingSupported(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ constexpr bool gameplay_recording_supported = false;
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(gameplay_recording_supported);
+}
+
void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
@@ -1631,6 +1641,14 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe
rb.PushCopyObjects(friend_invitation_storage_channel_event.readable);
}
+void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(
+ Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ERR_NO_DATA_IN_CHANNEL);
+}
+
void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
Core::System& system) {
auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel());
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 50737432c..f5db41ac8 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -266,6 +266,7 @@ private:
void SetTerminateResult(Kernel::HLERequestContext& ctx);
void GetDisplayVersion(Kernel::HLERequestContext& ctx);
void GetDesiredLanguage(Kernel::HLERequestContext& ctx);
+ void IsGamePlayRecordingSupported(Kernel::HLERequestContext& ctx);
void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx);
void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx);
void NotifyRunning(Kernel::HLERequestContext& ctx);
@@ -288,6 +289,7 @@ private:
void GetPreviousProgramIndex(Kernel::HLERequestContext& ctx);
void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
void GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx);
+ void TryPopFromFriendInvitationStorageChannel(Kernel::HLERequestContext& ctx);
bool launch_popped_application_specific = false;
bool launch_popped_account_preselect = false;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 5efc1237e..4cee4838c 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -126,14 +126,23 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
}
+ // If ns_late is higher than the update rate ignore the delay
+ if (ns_late > motion_update_ns) {
+ ns_late = {};
+ }
+
core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event);
}
void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
- for (const auto& controller : controllers) {
- controller->OnMotionUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
+ controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(
+ core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
+
+ // If ns_late is higher than the update rate ignore the delay
+ if (ns_late > motion_update_ns) {
+ ns_late = {};
}
core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event);
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index ef5176bea..8372e170c 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -21,6 +21,93 @@ enum class RequestState : u32 {
Connected = 3,
};
+struct IpAddressSetting {
+ bool is_automatic{};
+ Network::IPv4Address current_address{};
+ Network::IPv4Address subnet_mask{};
+ Network::IPv4Address gateway{};
+};
+static_assert(sizeof(IpAddressSetting) == 0xD, "IpAddressSetting has incorrect size.");
+
+struct DnsSetting {
+ bool is_automatic{};
+ Network::IPv4Address primary_dns{};
+ Network::IPv4Address secondary_dns{};
+};
+static_assert(sizeof(DnsSetting) == 0x9, "DnsSetting has incorrect size.");
+
+struct ProxySetting {
+ bool enabled{};
+ INSERT_PADDING_BYTES(1);
+ u16 port{};
+ std::array<char, 0x64> proxy_server{};
+ bool automatic_auth_enabled{};
+ std::array<char, 0x20> user{};
+ std::array<char, 0x20> password{};
+ INSERT_PADDING_BYTES(1);
+};
+static_assert(sizeof(ProxySetting) == 0xAA, "ProxySetting has incorrect size.");
+
+struct IpSettingData {
+ IpAddressSetting ip_address_setting{};
+ DnsSetting dns_setting{};
+ ProxySetting proxy_setting{};
+ u16 mtu{};
+};
+static_assert(sizeof(IpSettingData) == 0xC2, "IpSettingData has incorrect size.");
+
+struct SfWirelessSettingData {
+ u8 ssid_length{};
+ std::array<char, 0x20> ssid{};
+ u8 unknown_1{};
+ u8 unknown_2{};
+ u8 unknown_3{};
+ std::array<char, 0x41> passphrase{};
+};
+static_assert(sizeof(SfWirelessSettingData) == 0x65, "SfWirelessSettingData has incorrect size.");
+
+struct NifmWirelessSettingData {
+ u8 ssid_length{};
+ std::array<char, 0x21> ssid{};
+ u8 unknown_1{};
+ INSERT_PADDING_BYTES(1);
+ u32 unknown_2{};
+ u32 unknown_3{};
+ std::array<char, 0x41> passphrase{};
+ INSERT_PADDING_BYTES(3);
+};
+static_assert(sizeof(NifmWirelessSettingData) == 0x70,
+ "NifmWirelessSettingData has incorrect size.");
+
+#pragma pack(push, 1)
+struct SfNetworkProfileData {
+ IpSettingData ip_setting_data{};
+ u128 uuid{};
+ std::array<char, 0x40> network_name{};
+ u8 unknown_1{};
+ u8 unknown_2{};
+ u8 unknown_3{};
+ u8 unknown_4{};
+ SfWirelessSettingData wireless_setting_data{};
+ INSERT_PADDING_BYTES(1);
+};
+static_assert(sizeof(SfNetworkProfileData) == 0x17C, "SfNetworkProfileData has incorrect size.");
+
+struct NifmNetworkProfileData {
+ u128 uuid{};
+ std::array<char, 0x40> network_name{};
+ u32 unknown_1{};
+ u32 unknown_2{};
+ u8 unknown_3{};
+ u8 unknown_4{};
+ INSERT_PADDING_BYTES(2);
+ NifmWirelessSettingData wireless_setting_data{};
+ IpSettingData ip_setting_data{};
+};
+static_assert(sizeof(NifmNetworkProfileData) == 0x18E,
+ "NifmNetworkProfileData has incorrect size.");
+#pragma pack(pop)
+
class IScanRequest final : public ServiceFramework<IScanRequest> {
public:
explicit IScanRequest(Core::System& system_) : ServiceFramework{system_, "IScanRequest"} {
@@ -128,7 +215,11 @@ private:
void GetAppletInfo(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
- IPC::ResponseBuilder rb{ctx, 8};
+ std::vector<u8> out_buffer(ctx.GetWriteBufferSize());
+
+ ctx.WriteBuffer(out_buffer);
+
+ IPC::ResponseBuilder rb{ctx, 5};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0);
rb.Push<u32>(0);
@@ -179,6 +270,46 @@ private:
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IRequest>(system);
}
+ void GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_NIFM, "(STUBBED) called");
+
+ const SfNetworkProfileData network_profile_data{
+ .ip_setting_data{
+ .ip_address_setting{
+ .is_automatic{true},
+ .current_address{192, 168, 1, 100},
+ .subnet_mask{255, 255, 255, 0},
+ .gateway{192, 168, 1, 1},
+ },
+ .dns_setting{
+ .is_automatic{true},
+ .primary_dns{1, 1, 1, 1},
+ .secondary_dns{1, 0, 0, 1},
+ },
+ .proxy_setting{
+ .enabled{false},
+ .port{},
+ .proxy_server{},
+ .automatic_auth_enabled{},
+ .user{},
+ .password{},
+ },
+ .mtu{1500},
+ },
+ .uuid{0xdeadbeef, 0xdeadbeef},
+ .network_name{"yuzu Network"},
+ .wireless_setting_data{
+ .ssid_length{12},
+ .ssid{"yuzu Network"},
+ .passphrase{"yuzupassword"},
+ },
+ };
+
+ ctx.WriteBuffer(network_profile_data);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
@@ -210,6 +341,34 @@ private:
rb.PushIpcInterface<INetworkProfile>(system);
rb.PushRaw<u128>(uuid);
}
+ void GetCurrentIpConfigInfo(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_NIFM, "(STUBBED) called");
+
+ struct IpConfigInfo {
+ IpAddressSetting ip_address_setting;
+ DnsSetting dns_setting;
+ };
+ static_assert(sizeof(IpConfigInfo) == sizeof(IpAddressSetting) + sizeof(DnsSetting),
+ "IpConfigInfo has incorrect size.");
+
+ const IpConfigInfo ip_config_info{
+ .ip_address_setting{
+ .is_automatic{true},
+ .current_address{192, 168, 1, 100},
+ .subnet_mask{255, 255, 255, 0},
+ .gateway{192, 168, 1, 1},
+ },
+ .dns_setting{
+ .is_automatic{true},
+ .primary_dns{1, 1, 1, 1},
+ .secondary_dns{1, 0, 0, 1},
+ },
+ };
+
+ IPC::ResponseBuilder rb{ctx, 2 + sizeof(IpConfigInfo) / sizeof(u32)};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushRaw<IpConfigInfo>(ip_config_info);
+ }
void IsWirelessCommunicationEnabled(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
@@ -248,7 +407,7 @@ IGeneralService::IGeneralService(Core::System& system_)
{1, &IGeneralService::GetClientId, "GetClientId"},
{2, &IGeneralService::CreateScanRequest, "CreateScanRequest"},
{4, &IGeneralService::CreateRequest, "CreateRequest"},
- {5, nullptr, "GetCurrentNetworkProfile"},
+ {5, &IGeneralService::GetCurrentNetworkProfile, "GetCurrentNetworkProfile"},
{6, nullptr, "EnumerateNetworkInterfaces"},
{7, nullptr, "EnumerateNetworkProfiles"},
{8, nullptr, "GetNetworkProfile"},
@@ -258,7 +417,7 @@ IGeneralService::IGeneralService(Core::System& system_)
{12, &IGeneralService::GetCurrentIpAddress, "GetCurrentIpAddress"},
{13, nullptr, "GetCurrentAccessPointOld"},
{14, &IGeneralService::CreateTemporaryNetworkProfile, "CreateTemporaryNetworkProfile"},
- {15, nullptr, "GetCurrentIpConfigInfo"},
+ {15, &IGeneralService::GetCurrentIpConfigInfo, "GetCurrentIpConfigInfo"},
{16, nullptr, "SetWirelessCommunicationEnabled"},
{17, &IGeneralService::IsWirelessCommunicationEnabled, "IsWirelessCommunicationEnabled"},
{18, nullptr, "GetInternetConnectionStatus"},
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index 86ecc5b97..d5b3b17a5 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -25,8 +25,8 @@ public:
{10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old2>, "SaveReportWithUserOld2"},
{10104, &PlayReport::SaveReport<Core::Reporter::PlayReportType::New>, "SaveReport"},
{10105, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"},
- {10200, nullptr, "RequestImmediateTransmission"},
- {10300, nullptr, "GetTransmissionStatus"},
+ {10200, &PlayReport::RequestImmediateTransmission, "RequestImmediateTransmission"},
+ {10300, &PlayReport::GetTransmissionStatus, "GetTransmissionStatus"},
{10400, &PlayReport::GetSystemSessionId, "GetSystemSessionId"},
{20100, &PlayReport::SaveSystemReport, "SaveSystemReport"},
{20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
@@ -108,6 +108,23 @@ private:
rb.Push(RESULT_SUCCESS);
}
+ void RequestImmediateTransmission(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_PREPO, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
+
+ void GetTransmissionStatus(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_PREPO, "(STUBBED) called");
+
+ constexpr s32 status = 0;
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(status);
+ }
+
void GetSystemSessionId(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_PREPO, "(STUBBED) called");
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index 22f540914..0b306b87a 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -263,11 +263,15 @@ void BSD::GetSockOpt(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called. fd={} level={} optname=0x{:x}", fd, level, optname);
+ std::vector<u8> optval(ctx.GetWriteBufferSize());
+
+ ctx.WriteBuffer(optval);
+
IPC::ResponseBuilder rb{ctx, 5};
rb.Push(RESULT_SUCCESS);
rb.Push<s32>(-1);
rb.PushEnum(Errno::NOTCONN);
- rb.Push<u32>(0);
+ rb.Push<u32>(static_cast<u32>(optval.size()));
}
void BSD::Listen(Kernel::HLERequestContext& ctx) {
@@ -416,6 +420,16 @@ void BSD::Close(Kernel::HLERequestContext& ctx) {
BuildErrnoResponse(ctx, CloseImpl(fd));
}
+void BSD::EventFd(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const u64 initval = rp.Pop<u64>();
+ const u32 flags = rp.Pop<u32>();
+
+ LOG_WARNING(Service, "(STUBBED) called. initval={}, flags={}", initval, flags);
+
+ BuildErrnoResponse(ctx, Errno::SUCCESS);
+}
+
template <typename Work>
void BSD::ExecuteWork(Kernel::HLERequestContext& ctx, Work work) {
work.Execute(this);
@@ -841,7 +855,7 @@ BSD::BSD(Core::System& system_, const char* name) : ServiceFramework{system_, na
{28, nullptr, "GetResourceStatistics"},
{29, nullptr, "RecvMMsg"},
{30, nullptr, "SendMMsg"},
- {31, nullptr, "EventFd"},
+ {31, &BSD::EventFd, "EventFd"},
{32, nullptr, "RegisterResourceStatisticsName"},
{33, nullptr, "Initialize2"},
};
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index f5831dd48..1d2df9c61 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -136,6 +136,7 @@ private:
void SendTo(Kernel::HLERequestContext& ctx);
void Write(Kernel::HLERequestContext& ctx);
void Close(Kernel::HLERequestContext& ctx);
+ void EventFd(Kernel::HLERequestContext& ctx);
template <typename Work>
void ExecuteWork(Kernel::HLERequestContext& ctx, Work work);