mirror of
https://git.eden-emu.dev/archive/citron
synced 2026-03-23 01:56:08 -04:00
feat(hle): implement misc service stubs for QLaunch compatibility
- audctl: Add GetAudioController (cmd 5000) returning IAudioController - vi: Improve display service with better non-default display handling - psc/ovln: Add GetReceiveEventHandle for overlay notifications - omm: Add GetNotificationMessageEventHandle for power state - olsc: Implement GetNativeHandle returning valid event - prepo: Add SaveSystemReport2 (cmd 20102) stub
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
@@ -72,7 +72,7 @@ IAudioController::IAudioController(Core::System& system_)
|
|||||||
{50001, D<&IAudioController::OverrideDefaultTargetForDebug>, "OverrideDefaultTargetForDebug"}, // [19.0.0-19.0.1]
|
{50001, D<&IAudioController::OverrideDefaultTargetForDebug>, "OverrideDefaultTargetForDebug"}, // [19.0.0-19.0.1]
|
||||||
{50003, D<&IAudioController::SetForceOverrideExternalDeviceNameForDebug>, "SetForceOverrideExternalDeviceNameForDebug"}, // [19.0.0+]
|
{50003, D<&IAudioController::SetForceOverrideExternalDeviceNameForDebug>, "SetForceOverrideExternalDeviceNameForDebug"}, // [19.0.0+]
|
||||||
{50004, D<&IAudioController::ClearForceOverrideExternalDeviceNameForDebug>, "ClearForceOverrideExternalDeviceNameForDebug"}, // [19.0.0+]
|
{50004, D<&IAudioController::ClearForceOverrideExternalDeviceNameForDebug>, "ClearForceOverrideExternalDeviceNameForDebug"}, // [19.0.0+]
|
||||||
{5000, nullptr, "Unknown5000"}, // [19.0.0+]
|
{5000, D<&IAudioController::GetAudioController>, "GetAudioController"}, // [19.0.0+]
|
||||||
{10200, D<&IAudioController::Unknown10200>, "Unknown10200"}, // [20.0.0+]
|
{10200, D<&IAudioController::Unknown10200>, "Unknown10200"}, // [20.0.0+]
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@@ -407,4 +407,11 @@ Result IAudioController::Unknown10200() {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result IAudioController::GetAudioController(
|
||||||
|
Out<SharedPointer<IAudioController>> out_audio_controller) {
|
||||||
|
LOG_DEBUG(Audio, "called GetAudioController [19.0.0+]");
|
||||||
|
*out_audio_controller = std::make_shared<IAudioController>(system);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Service::Audio
|
} // namespace Service::Audio
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -90,6 +90,7 @@ private:
|
|||||||
Result OverrideDefaultTargetForDebug(u32 target); // [19.0.0-19.0.1]
|
Result OverrideDefaultTargetForDebug(u32 target); // [19.0.0-19.0.1]
|
||||||
Result SetForceOverrideExternalDeviceNameForDebug(InLargeData<std::array<u8, 0x80>, BufferAttr_HipcMapAlias> device_name); // [19.0.0+]
|
Result SetForceOverrideExternalDeviceNameForDebug(InLargeData<std::array<u8, 0x80>, BufferAttr_HipcMapAlias> device_name); // [19.0.0+]
|
||||||
Result ClearForceOverrideExternalDeviceNameForDebug(); // [19.0.0+]
|
Result ClearForceOverrideExternalDeviceNameForDebug(); // [19.0.0+]
|
||||||
|
Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller); // [19.0.0+]
|
||||||
Result Unknown10200(); // [20.0.0+]
|
Result Unknown10200(); // [20.0.0+]
|
||||||
|
|
||||||
KernelHelpers::ServiceContext service_context;
|
KernelHelpers::ServiceContext service_context;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
@@ -7,7 +8,8 @@
|
|||||||
namespace Service::OLSC {
|
namespace Service::OLSC {
|
||||||
|
|
||||||
INativeHandleHolder::INativeHandleHolder(Core::System& system_)
|
INativeHandleHolder::INativeHandleHolder(Core::System& system_)
|
||||||
: ServiceFramework{system_, "INativeHandleHolder"} {
|
: ServiceFramework{system_, "INativeHandleHolder"},
|
||||||
|
service_context{system_, "INativeHandleHolder"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&INativeHandleHolder::GetNativeHandle>, "GetNativeHandle"},
|
{0, D<&INativeHandleHolder::GetNativeHandle>, "GetNativeHandle"},
|
||||||
@@ -15,13 +17,17 @@ INativeHandleHolder::INativeHandleHolder(Core::System& system_)
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
|
event = service_context.CreateEvent("INativeHandleHolder:Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
INativeHandleHolder::~INativeHandleHolder() = default;
|
INativeHandleHolder::~INativeHandleHolder() {
|
||||||
|
service_context.CloseEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
Result INativeHandleHolder::GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
Result INativeHandleHolder::GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
LOG_WARNING(Service_OLSC, "(STUBBED) called");
|
LOG_DEBUG(Service_OLSC, "called");
|
||||||
*out_event = nullptr;
|
*out_event = &event->GetReadableEvent();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
#include "core/hle/service/cmif_types.h"
|
||||||
|
#include "core/hle/service/kernel_helpers.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class KReadableEvent;
|
class KReadableEvent;
|
||||||
|
class KEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Service::OLSC {
|
namespace Service::OLSC {
|
||||||
@@ -17,6 +22,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Result GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
Result GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
|
|
||||||
|
KernelHelpers::ServiceContext service_context;
|
||||||
|
Kernel::KEvent* event;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::OLSC
|
} // namespace Service::OLSC
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/kernel/k_event.h"
|
||||||
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/omm/power_state_interface.h"
|
#include "core/hle/service/omm/power_state_interface.h"
|
||||||
|
|
||||||
namespace Service::OMM {
|
namespace Service::OMM {
|
||||||
|
|
||||||
IPowerStateInterface::IPowerStateInterface(Core::System& system_)
|
IPowerStateInterface::IPowerStateInterface(Core::System& system_)
|
||||||
: ServiceFramework{system_, "spsm"} {
|
: ServiceFramework{system_, "spsm"}, service_context{system_, "IPowerStateInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "GetState"},
|
{0, nullptr, "GetState"},
|
||||||
{1, nullptr, "EnterSleep"},
|
{1, nullptr, "EnterSleep"},
|
||||||
{2, nullptr, "GetLastWakeReason"},
|
{2, nullptr, "GetLastWakeReason"},
|
||||||
{3, nullptr, "Shutdown"},
|
{3, nullptr, "Shutdown"},
|
||||||
{4, nullptr, "GetNotificationMessageEventHandle"},
|
{4, D<&IPowerStateInterface::GetNotificationMessageEventHandle>, "GetNotificationMessageEventHandle"},
|
||||||
{5, nullptr, "ReceiveNotificationMessage"},
|
{5, nullptr, "ReceiveNotificationMessage"},
|
||||||
{6, nullptr, "AnalyzeLogForLastSleepWakeSequence"},
|
{6, nullptr, "AnalyzeLogForLastSleepWakeSequence"},
|
||||||
{7, nullptr, "ResetEventLog"},
|
{7, nullptr, "ResetEventLog"},
|
||||||
@@ -25,8 +27,18 @@ IPowerStateInterface::IPowerStateInterface(Core::System& system_)
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
notification_event = service_context.CreateEvent("IPowerStateInterface:NotificationEvent");
|
||||||
}
|
}
|
||||||
|
|
||||||
IPowerStateInterface::~IPowerStateInterface() = default;
|
IPowerStateInterface::~IPowerStateInterface() {
|
||||||
|
service_context.CloseEvent(notification_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IPowerStateInterface::GetNotificationMessageEventHandle(
|
||||||
|
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
|
LOG_DEBUG(Service, "called");
|
||||||
|
*out_event = ¬ification_event->GetReadableEvent();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Service::OMM
|
} // namespace Service::OMM
|
||||||
|
|||||||
@@ -3,8 +3,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/cmif_types.h"
|
||||||
|
#include "core/hle/service/kernel_helpers.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
class KEvent;
|
||||||
|
class KReadableEvent;
|
||||||
|
} // namespace Kernel
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
@@ -15,6 +22,12 @@ class IPowerStateInterface final : public ServiceFramework<IPowerStateInterface>
|
|||||||
public:
|
public:
|
||||||
explicit IPowerStateInterface(Core::System& system_);
|
explicit IPowerStateInterface(Core::System& system_);
|
||||||
~IPowerStateInterface() override;
|
~IPowerStateInterface() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Result GetNotificationMessageEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
|
|
||||||
|
KernelHelpers::ServiceContext service_context;
|
||||||
|
Kernel::KEvent* notification_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::OMM
|
} // namespace Service::OMM
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public:
|
|||||||
{10500, &PlayReport::SendReportWithUser, "SendReportWithUser"},
|
{10500, &PlayReport::SendReportWithUser, "SendReportWithUser"},
|
||||||
{20100, &PlayReport::SaveSystemReport, "SaveSystemReport"},
|
{20100, &PlayReport::SaveSystemReport, "SaveSystemReport"},
|
||||||
{20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
|
{20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
|
||||||
|
{20102, &PlayReport::SaveSystemReport2, "SaveSystemReport2"},
|
||||||
{20200, &PlayReport::SetOperationMode, "SetOperationMode"},
|
{20200, &PlayReport::SetOperationMode, "SetOperationMode"},
|
||||||
{30100, &PlayReport::ClearStorage, "ClearStorage"},
|
{30100, &PlayReport::ClearStorage, "ClearStorage"},
|
||||||
{30200, &PlayReport::ClearStatistics, "ClearStatistics"},
|
{30200, &PlayReport::ClearStatistics, "ClearStatistics"},
|
||||||
@@ -160,6 +161,13 @@ private:
|
|||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveSystemReport2(HLERequestContext& ctx) {
|
||||||
|
LOG_WARNING(Service_PREPO, "(STUBBED) called");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
void SetOperationMode(HLERequestContext& ctx) {
|
void SetOperationMode(HLERequestContext& ctx) {
|
||||||
LOG_WARNING(Service_PREPO, "(STUBBED) called");
|
LOG_WARNING(Service_PREPO, "(STUBBED) called");
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,36 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/kernel/k_event.h"
|
||||||
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/psc/ovln/receiver.h"
|
#include "core/hle/service/psc/ovln/receiver.h"
|
||||||
|
|
||||||
namespace Service::PSC {
|
namespace Service::PSC {
|
||||||
|
|
||||||
IReceiver::IReceiver(Core::System& system_) : ServiceFramework{system_, "IReceiver"} {
|
IReceiver::IReceiver(Core::System& system_)
|
||||||
|
: ServiceFramework{system_, "IReceiver"}, service_context{system_, "IReceiver"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "AddSource"},
|
{0, nullptr, "AddSource"},
|
||||||
{1, nullptr, "RemoveSource"},
|
{1, nullptr, "RemoveSource"},
|
||||||
{2, nullptr, "GetReceiveEventHandle"},
|
{2, D<&IReceiver::GetReceiveEventHandle>, "GetReceiveEventHandle"},
|
||||||
{3, nullptr, "Receive"},
|
{3, nullptr, "Receive"},
|
||||||
{4, nullptr, "ReceiveWithTick"},
|
{4, nullptr, "ReceiveWithTick"},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
event = service_context.CreateEvent("IReceiver:Event");
|
||||||
}
|
}
|
||||||
|
|
||||||
IReceiver::~IReceiver() = default;
|
IReceiver::~IReceiver() {
|
||||||
|
service_context.CloseEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IReceiver::GetReceiveEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
|
LOG_DEBUG(Service_PSC, "called");
|
||||||
|
*out_event = &event->GetReadableEvent();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Service::PSC
|
} // namespace Service::PSC
|
||||||
|
|||||||
@@ -3,14 +3,27 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/hle/service/cmif_types.h"
|
||||||
|
#include "core/hle/service/kernel_helpers.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
class KEvent;
|
||||||
|
class KReadableEvent;
|
||||||
|
} // namespace Kernel
|
||||||
|
|
||||||
namespace Service::PSC {
|
namespace Service::PSC {
|
||||||
|
|
||||||
class IReceiver final : public ServiceFramework<IReceiver> {
|
class IReceiver final : public ServiceFramework<IReceiver> {
|
||||||
public:
|
public:
|
||||||
explicit IReceiver(Core::System& system_);
|
explicit IReceiver(Core::System& system_);
|
||||||
~IReceiver() override;
|
~IReceiver() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Result GetReceiveEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
|
|
||||||
|
KernelHelpers::ServiceContext service_context;
|
||||||
|
Kernel::KEvent* event;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::PSC
|
} // namespace Service::PSC
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/nvnflinger/hos_binder_driver.h"
|
#include "core/hle/service/nvnflinger/hos_binder_driver.h"
|
||||||
#include "core/hle/service/nvnflinger/parcel.h"
|
#include "core/hle/service/nvnflinger/parcel.h"
|
||||||
@@ -88,8 +91,12 @@ Result IApplicationDisplayService::OpenDisplay(Out<u64> out_display_id, DisplayN
|
|||||||
LOG_WARNING(Service_VI, "(STUBBED) called");
|
LOG_WARNING(Service_VI, "(STUBBED) called");
|
||||||
|
|
||||||
display_name[display_name.size() - 1] = '\0';
|
display_name[display_name.size() - 1] = '\0';
|
||||||
ASSERT_MSG(strcmp(display_name.data(), "Default") == 0,
|
if (strcmp(display_name.data(), "Default") != 0) {
|
||||||
"Non-default displays aren't supported yet");
|
LOG_WARNING(Service_VI, "Non-default display '{}' requested, using Default display",
|
||||||
|
display_name.data());
|
||||||
|
// Use Default display for non-default display requests
|
||||||
|
R_RETURN(m_container->OpenDisplay(out_display_id, DisplayName{"Default"}));
|
||||||
|
}
|
||||||
|
|
||||||
R_RETURN(m_container->OpenDisplay(out_display_id, display_name));
|
R_RETURN(m_container->OpenDisplay(out_display_id, display_name));
|
||||||
}
|
}
|
||||||
@@ -142,14 +149,39 @@ Result IApplicationDisplayService::SetLayerScalingMode(NintendoScaleMode scale_m
|
|||||||
|
|
||||||
Result IApplicationDisplayService::ListDisplays(
|
Result IApplicationDisplayService::ListDisplays(
|
||||||
Out<u64> out_count, OutArray<DisplayInfo, BufferAttr_HipcMapAlias> out_displays) {
|
Out<u64> out_count, OutArray<DisplayInfo, BufferAttr_HipcMapAlias> out_displays) {
|
||||||
LOG_WARNING(Service_VI, "(STUBBED) called");
|
LOG_DEBUG(Service_VI, "called");
|
||||||
|
|
||||||
if (out_displays.size() > 0) {
|
// QLaunch expects multiple displays: Default, Edid, Internal, External, Null
|
||||||
out_displays[0] = DisplayInfo{};
|
struct DisplayEntry {
|
||||||
*out_count = 1;
|
const char* name;
|
||||||
} else {
|
u8 has_limited_layers;
|
||||||
*out_count = 0;
|
u64 max_layers;
|
||||||
|
u64 width;
|
||||||
|
u64 height;
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr std::array<DisplayEntry, 5> display_entries{{
|
||||||
|
{"Default", 1, 1, 1920, 1080},
|
||||||
|
{"Edid", 1, 1, 1920, 1080},
|
||||||
|
{"Internal", 1, 1, 1280, 720},
|
||||||
|
{"External", 1, 1, 1920, 1080},
|
||||||
|
{"Null", 0, 0, 0, 0},
|
||||||
|
}};
|
||||||
|
|
||||||
|
const u64 display_count =
|
||||||
|
std::min(static_cast<u64>(display_entries.size()), out_displays.size());
|
||||||
|
|
||||||
|
for (u64 i = 0; i < display_count; ++i) {
|
||||||
|
DisplayInfo info{};
|
||||||
|
std::strncpy(info.display_name.data(), display_entries[i].name,
|
||||||
|
info.display_name.size() - 1);
|
||||||
|
info.has_limited_layers = display_entries[i].has_limited_layers;
|
||||||
|
info.max_layers = display_entries[i].max_layers;
|
||||||
|
info.width = display_entries[i].width;
|
||||||
|
info.height = display_entries[i].height;
|
||||||
|
out_displays[i] = info;
|
||||||
}
|
}
|
||||||
|
*out_count = display_count;
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user