diff options
Diffstat (limited to 'src/core/hle/service')
23 files changed, 443 insertions, 230 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 3f009d2b7..9c44e27c6 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <algorithm> #include <array> #include <cinttypes> #include <cstring> -#include <stack> #include "audio_core/audio_renderer.h" #include "core/core.h" #include "core/file_sys/savedata_factory.h" @@ -93,38 +93,84 @@ void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) } IAudioController::IAudioController() : ServiceFramework("IAudioController") { + // clang-format off static const FunctionInfo functions[] = { {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"}, - {1, &IAudioController::GetMainAppletExpectedMasterVolume, - "GetMainAppletExpectedMasterVolume"}, - {2, &IAudioController::GetLibraryAppletExpectedMasterVolume, - "GetLibraryAppletExpectedMasterVolume"}, - {3, nullptr, "ChangeMainAppletMasterVolume"}, - {4, nullptr, "SetTransparentVolumeRate"}, + {1, &IAudioController::GetMainAppletExpectedMasterVolume, "GetMainAppletExpectedMasterVolume"}, + {2, &IAudioController::GetLibraryAppletExpectedMasterVolume, "GetLibraryAppletExpectedMasterVolume"}, + {3, &IAudioController::ChangeMainAppletMasterVolume, "ChangeMainAppletMasterVolume"}, + {4, &IAudioController::SetTransparentAudioRate, "SetTransparentVolumeRate"}, }; + // clang-format on + RegisterHandlers(functions); } IAudioController::~IAudioController() = default; void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const float main_applet_volume_tmp = rp.Pop<float>(); + const float library_applet_volume_tmp = rp.Pop<float>(); + + LOG_DEBUG(Service_AM, "called. main_applet_volume={}, library_applet_volume={}", + main_applet_volume_tmp, library_applet_volume_tmp); + + // Ensure the volume values remain within the 0-100% range + main_applet_volume = std::clamp(main_applet_volume_tmp, min_allowed_volume, max_allowed_volume); + library_applet_volume = + std::clamp(library_applet_volume_tmp, min_allowed_volume, max_allowed_volume); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + LOG_DEBUG(Service_AM, "called. main_applet_volume={}", main_applet_volume); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(volume); + rb.Push(main_applet_volume); } void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + LOG_DEBUG(Service_AM, "called. library_applet_volume={}", library_applet_volume); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(volume); + rb.Push(library_applet_volume); +} + +void IAudioController::ChangeMainAppletMasterVolume(Kernel::HLERequestContext& ctx) { + struct Parameters { + float volume; + s64 fade_time_ns; + }; + static_assert(sizeof(Parameters) == 16); + + IPC::RequestParser rp{ctx}; + const auto parameters = rp.PopRaw<Parameters>(); + + LOG_DEBUG(Service_AM, "called. volume={}, fade_time_ns={}", parameters.volume, + parameters.fade_time_ns); + + main_applet_volume = std::clamp(parameters.volume, min_allowed_volume, max_allowed_volume); + fade_time_ns = std::chrono::nanoseconds{parameters.fade_time_ns}; + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void IAudioController::SetTransparentAudioRate(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const float transparent_volume_rate_tmp = rp.Pop<float>(); + + LOG_DEBUG(Service_AM, "called. transparent_volume_rate={}", transparent_volume_rate_tmp); + + // Clamp volume range to 0-100%. + transparent_volume_rate = + std::clamp(transparent_volume_rate_tmp, min_allowed_volume, max_allowed_volume); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); } IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") { @@ -169,7 +215,21 @@ IDisplayController::IDisplayController() : ServiceFramework("IDisplayController" IDisplayController::~IDisplayController() = default; -IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {} +IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "NotifyMessageToHomeMenuForDebug"}, + {1, nullptr, "OpenMainApplication"}, + {10, nullptr, "EmulateButtonEvent"}, + {20, nullptr, "InvalidateTransitionLayer"}, + {30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"}, + {40, nullptr, "GetAppletResourceUsageInfo"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + IDebugFunctions::~IDebugFunctions() = default; ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index b6113cfdd..565dd8e9e 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -4,6 +4,7 @@ #pragma once +#include <chrono> #include <memory> #include <queue> #include "core/hle/kernel/writable_event.h" @@ -81,8 +82,21 @@ private: void SetExpectedMasterVolume(Kernel::HLERequestContext& ctx); void GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); void GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx); + void ChangeMainAppletMasterVolume(Kernel::HLERequestContext& ctx); + void SetTransparentAudioRate(Kernel::HLERequestContext& ctx); - u32 volume{100}; + static constexpr float min_allowed_volume = 0.0f; + static constexpr float max_allowed_volume = 1.0f; + + float main_applet_volume{0.25f}; + float library_applet_volume{max_allowed_volume}; + float transparent_volume_rate{min_allowed_volume}; + + // Volume transition fade time in nanoseconds. + // e.g. If the main applet volume was 0% and was changed to 50% + // with a fade of 50ns, then over the course of 50ns, + // the volume will gradually fade up to 50% + std::chrono::nanoseconds fade_time_ns{0}; }; class IDisplayController final : public ServiceFramework<IDisplayController> { diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index 11eba4a12..cb4a1160d 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp @@ -8,44 +8,34 @@ #include <vector> #include <opus.h> +#include <opus_multistream.h> -#include "common/common_funcs.h" +#include "common/assert.h" #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/service/audio/hwopus.h" namespace Service::Audio { - +namespace { struct OpusDeleter { - void operator()(void* ptr) const { - operator delete(ptr); + void operator()(OpusMSDecoder* ptr) const { + opus_multistream_decoder_destroy(ptr); } }; -class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { -public: - IHardwareOpusDecoderManager(std::unique_ptr<OpusDecoder, OpusDeleter> decoder, u32 sample_rate, - u32 channel_count) - : ServiceFramework("IHardwareOpusDecoderManager"), decoder(std::move(decoder)), - sample_rate(sample_rate), channel_count(channel_count) { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IHardwareOpusDecoderManager::DecodeInterleavedOld, "DecodeInterleavedOld"}, - {1, nullptr, "SetContext"}, - {2, nullptr, "DecodeInterleavedForMultiStreamOld"}, - {3, nullptr, "SetContextForMultiStream"}, - {4, &IHardwareOpusDecoderManager::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"}, - {5, nullptr, "DecodeInterleavedForMultiStreamWithPerfOld"}, - {6, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"}, - {7, nullptr, "DecodeInterleavedForMultiStream"}, - }; - // clang-format on +using OpusDecoderPtr = std::unique_ptr<OpusMSDecoder, OpusDeleter>; - RegisterHandlers(functions); - } +struct OpusPacketHeader { + // Packet size in bytes. + u32_be size; + // Indicates the final range of the codec's entropy coder. + u32_be final_range; +}; +static_assert(sizeof(OpusPacketHeader) == 0x8, "OpusHeader is an invalid size"); -private: +class OpusDecoderState { +public: /// Describes extra behavior that may be asked of the decoding context. enum class ExtraBehavior { /// No extra behavior. @@ -55,30 +45,27 @@ private: ResetContext, }; - void DecodeInterleavedOld(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Audio, "called"); - - DecodeInterleavedHelper(ctx, nullptr, ExtraBehavior::None); - } - - void DecodeInterleavedWithPerfOld(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Audio, "called"); - - u64 performance = 0; - DecodeInterleavedHelper(ctx, &performance, ExtraBehavior::None); - } - - void DecodeInterleaved(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Audio, "called"); - - IPC::RequestParser rp{ctx}; - const auto extra_behavior = - rp.Pop<bool>() ? ExtraBehavior::ResetContext : ExtraBehavior::None; + enum class PerfTime { + Disabled, + Enabled, + }; - u64 performance = 0; - DecodeInterleavedHelper(ctx, &performance, extra_behavior); + explicit OpusDecoderState(OpusDecoderPtr decoder, u32 sample_rate, u32 channel_count) + : decoder{std::move(decoder)}, sample_rate{sample_rate}, channel_count{channel_count} {} + + // Decodes interleaved Opus packets. Optionally allows reporting time taken to + // perform the decoding, as well as any relevant extra behavior. + void DecodeInterleaved(Kernel::HLERequestContext& ctx, PerfTime perf_time, + ExtraBehavior extra_behavior) { + if (perf_time == PerfTime::Disabled) { + DecodeInterleavedHelper(ctx, nullptr, extra_behavior); + } else { + u64 performance = 0; + DecodeInterleavedHelper(ctx, &performance, extra_behavior); + } } +private: void DecodeInterleavedHelper(Kernel::HLERequestContext& ctx, u64* performance, ExtraBehavior extra_behavior) { u32 consumed = 0; @@ -89,8 +76,7 @@ private: ResetDecoderContext(); } - if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples, - performance)) { + if (!DecodeOpusData(consumed, sample_count, ctx.ReadBuffer(), samples, performance)) { LOG_ERROR(Audio, "Failed to decode opus data"); IPC::ResponseBuilder rb{ctx, 2}; // TODO(ogniK): Use correct error code @@ -109,27 +95,27 @@ private: ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16)); } - bool Decoder_DecodeInterleaved(u32& consumed, u32& sample_count, const std::vector<u8>& input, - std::vector<opus_int16>& output, u64* out_performance_time) { + bool DecodeOpusData(u32& consumed, u32& sample_count, const std::vector<u8>& input, + std::vector<opus_int16>& output, u64* out_performance_time) const { const auto start_time = std::chrono::high_resolution_clock::now(); const std::size_t raw_output_sz = output.size() * sizeof(opus_int16); - if (sizeof(OpusHeader) > input.size()) { + if (sizeof(OpusPacketHeader) > input.size()) { LOG_ERROR(Audio, "Input is smaller than the header size, header_sz={}, input_sz={}", - sizeof(OpusHeader), input.size()); + sizeof(OpusPacketHeader), input.size()); return false; } - OpusHeader hdr{}; - std::memcpy(&hdr, input.data(), sizeof(OpusHeader)); - if (sizeof(OpusHeader) + static_cast<u32>(hdr.sz) > input.size()) { + OpusPacketHeader hdr{}; + std::memcpy(&hdr, input.data(), sizeof(OpusPacketHeader)); + if (sizeof(OpusPacketHeader) + static_cast<u32>(hdr.size) > input.size()) { LOG_ERROR(Audio, "Input does not fit in the opus header size. data_sz={}, input_sz={}", - sizeof(OpusHeader) + static_cast<u32>(hdr.sz), input.size()); + sizeof(OpusPacketHeader) + static_cast<u32>(hdr.size), input.size()); return false; } - const auto frame = input.data() + sizeof(OpusHeader); + const auto frame = input.data() + sizeof(OpusPacketHeader); const auto decoded_sample_count = opus_packet_get_nb_samples( - frame, static_cast<opus_int32>(input.size() - sizeof(OpusHeader)), + frame, static_cast<opus_int32>(input.size() - sizeof(OpusPacketHeader)), static_cast<opus_int32>(sample_rate)); if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz) { LOG_ERROR( @@ -141,18 +127,18 @@ private: const int frame_size = (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count)); const auto out_sample_count = - opus_decode(decoder.get(), frame, hdr.sz, output.data(), frame_size, 0); + opus_multistream_decode(decoder.get(), frame, hdr.size, output.data(), frame_size, 0); if (out_sample_count < 0) { LOG_ERROR(Audio, "Incorrect sample count received from opus_decode, " "output_sample_count={}, frame_size={}, data_sz_from_hdr={}", - out_sample_count, frame_size, static_cast<u32>(hdr.sz)); + out_sample_count, frame_size, static_cast<u32>(hdr.size)); return false; } const auto end_time = std::chrono::high_resolution_clock::now() - start_time; sample_count = out_sample_count; - consumed = static_cast<u32>(sizeof(OpusHeader) + hdr.sz); + consumed = static_cast<u32>(sizeof(OpusPacketHeader) + hdr.size); if (out_performance_time != nullptr) { *out_performance_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time).count(); @@ -164,25 +150,86 @@ private: void ResetDecoderContext() { ASSERT(decoder != nullptr); - opus_decoder_ctl(decoder.get(), OPUS_RESET_STATE); + opus_multistream_decoder_ctl(decoder.get(), OPUS_RESET_STATE); } - struct OpusHeader { - u32_be sz; // Needs to be BE for some odd reason - INSERT_PADDING_WORDS(1); - }; - static_assert(sizeof(OpusHeader) == 0x8, "OpusHeader is an invalid size"); - - std::unique_ptr<OpusDecoder, OpusDeleter> decoder; + OpusDecoderPtr decoder; u32 sample_rate; u32 channel_count; }; -static std::size_t WorkerBufferSize(u32 channel_count) { +class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { +public: + explicit IHardwareOpusDecoderManager(OpusDecoderState decoder_state) + : ServiceFramework("IHardwareOpusDecoderManager"), decoder_state{std::move(decoder_state)} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &IHardwareOpusDecoderManager::DecodeInterleavedOld, "DecodeInterleavedOld"}, + {1, nullptr, "SetContext"}, + {2, nullptr, "DecodeInterleavedForMultiStreamOld"}, + {3, nullptr, "SetContextForMultiStream"}, + {4, &IHardwareOpusDecoderManager::DecodeInterleavedWithPerfOld, "DecodeInterleavedWithPerfOld"}, + {5, nullptr, "DecodeInterleavedForMultiStreamWithPerfOld"}, + {6, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"}, + {7, nullptr, "DecodeInterleavedForMultiStream"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void DecodeInterleavedOld(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Audio, "called"); + + decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Disabled, + OpusDecoderState::ExtraBehavior::None); + } + + void DecodeInterleavedWithPerfOld(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Audio, "called"); + + decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, + OpusDecoderState::ExtraBehavior::None); + } + + void DecodeInterleaved(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Audio, "called"); + + IPC::RequestParser rp{ctx}; + const auto extra_behavior = rp.Pop<bool>() ? OpusDecoderState::ExtraBehavior::ResetContext + : OpusDecoderState::ExtraBehavior::None; + + decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, extra_behavior); + } + + OpusDecoderState decoder_state; +}; + +std::size_t WorkerBufferSize(u32 channel_count) { ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); - return opus_decoder_get_size(static_cast<int>(channel_count)); + constexpr int num_streams = 1; + const int num_stereo_streams = channel_count == 2 ? 1 : 0; + return opus_multistream_decoder_get_size(num_streams, num_stereo_streams); } +// Creates the mapping table that maps the input channels to the particular +// output channels. In the stereo case, we map the left and right input channels +// to the left and right output channels respectively. +// +// However, in the monophonic case, we only map the one available channel +// to the sole output channel. We specify 255 for the would-be right channel +// as this is a special value defined by Opus to indicate to the decoder to +// ignore that channel. +std::array<u8, 2> CreateMappingTable(u32 channel_count) { + if (channel_count == 2) { + return {{0, 1}}; + } + + return {{0, 255}}; +} +} // Anonymous namespace + void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto sample_rate = rp.Pop<u32>(); @@ -220,10 +267,15 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) { const std::size_t worker_sz = WorkerBufferSize(channel_count); ASSERT_MSG(buffer_sz >= worker_sz, "Worker buffer too large"); - std::unique_ptr<OpusDecoder, OpusDeleter> decoder{ - static_cast<OpusDecoder*>(operator new(worker_sz))}; - if (const int err = opus_decoder_init(decoder.get(), sample_rate, channel_count)) { - LOG_ERROR(Audio, "Failed to init opus decoder with error={}", err); + const int num_stereo_streams = channel_count == 2 ? 1 : 0; + const auto mapping_table = CreateMappingTable(channel_count); + + int error = 0; + OpusDecoderPtr decoder{ + opus_multistream_decoder_create(sample_rate, static_cast<int>(channel_count), 1, + num_stereo_streams, mapping_table.data(), &error)}; + if (error != OPUS_OK || decoder == nullptr) { + LOG_ERROR(Audio, "Failed to create Opus decoder (error={}).", error); IPC::ResponseBuilder rb{ctx, 2}; // TODO(ogniK): Use correct error code rb.Push(ResultCode(-1)); @@ -232,8 +284,8 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IHardwareOpusDecoderManager>(std::move(decoder), sample_rate, - channel_count); + rb.PushIpcInterface<IHardwareOpusDecoderManager>( + OpusDecoderState{std::move(decoder), sample_rate, channel_count}); } HwOpus::HwOpus() : ServiceFramework("hwopus") { diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 54959edd8..f03fb629c 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -733,7 +733,10 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { FSP_SRV::~FSP_SRV() = default; void FSP_SRV::SetCurrentProcess(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + current_process_id = rp.Pop<u64>(); + + LOG_DEBUG(Service_FS, "called. current_process_id=0x{:016X}", current_process_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index 3a5f4e200..d7572ba7a 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h @@ -32,6 +32,7 @@ private: void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); FileSys::VirtualFile romfs; + u64 current_process_id = 0; }; } // namespace Service::FileSystem diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h index 929035034..e584b92ec 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ b/src/core/hle/service/hid/controllers/debug_pad.h @@ -41,20 +41,20 @@ private: struct PadState { union { u32_le raw{}; - BitField<0, 1, u32_le> a; - BitField<1, 1, u32_le> b; - BitField<2, 1, u32_le> x; - BitField<3, 1, u32_le> y; - BitField<4, 1, u32_le> l; - BitField<5, 1, u32_le> r; - BitField<6, 1, u32_le> zl; - BitField<7, 1, u32_le> zr; - BitField<8, 1, u32_le> plus; - BitField<9, 1, u32_le> minus; - BitField<10, 1, u32_le> d_left; - BitField<11, 1, u32_le> d_up; - BitField<12, 1, u32_le> d_right; - BitField<13, 1, u32_le> d_down; + BitField<0, 1, u32> a; + BitField<1, 1, u32> b; + BitField<2, 1, u32> x; + BitField<3, 1, u32> y; + BitField<4, 1, u32> l; + BitField<5, 1, u32> r; + BitField<6, 1, u32> zl; + BitField<7, 1, u32> zr; + BitField<8, 1, u32> plus; + BitField<9, 1, u32> minus; + BitField<10, 1, u32> d_left; + BitField<11, 1, u32> d_up; + BitField<12, 1, u32> d_right; + BitField<13, 1, u32> d_down; }; }; static_assert(sizeof(PadState) == 0x4, "PadState is an invalid size"); @@ -62,7 +62,7 @@ private: struct Attributes { union { u32_le raw{}; - BitField<0, 1, u32_le> connected; + BitField<0, 1, u32> connected; }; }; static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size"); diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 18c7a94e6..4ff50b3cd 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -39,13 +39,13 @@ public: union { u32_le raw{}; - BitField<0, 1, u32_le> pro_controller; - BitField<1, 1, u32_le> handheld; - BitField<2, 1, u32_le> joycon_dual; - BitField<3, 1, u32_le> joycon_left; - BitField<4, 1, u32_le> joycon_right; + BitField<0, 1, u32> pro_controller; + BitField<1, 1, u32> handheld; + BitField<2, 1, u32> joycon_dual; + BitField<3, 1, u32> joycon_left; + BitField<4, 1, u32> joycon_right; - BitField<6, 1, u32_le> pokeball; // TODO(ogniK): Confirm when possible + BitField<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible }; }; static_assert(sizeof(NPadType) == 4, "NPadType is an invalid size"); @@ -150,43 +150,43 @@ private: union { u64_le raw{}; // Button states - BitField<0, 1, u64_le> a; - BitField<1, 1, u64_le> b; - BitField<2, 1, u64_le> x; - BitField<3, 1, u64_le> y; - BitField<4, 1, u64_le> l_stick; - BitField<5, 1, u64_le> r_stick; - BitField<6, 1, u64_le> l; - BitField<7, 1, u64_le> r; - BitField<8, 1, u64_le> zl; - BitField<9, 1, u64_le> zr; - BitField<10, 1, u64_le> plus; - BitField<11, 1, u64_le> minus; + BitField<0, 1, u64> a; + BitField<1, 1, u64> b; + BitField<2, 1, u64> x; + BitField<3, 1, u64> y; + BitField<4, 1, u64> l_stick; + BitField<5, 1, u64> r_stick; + BitField<6, 1, u64> l; + BitField<7, 1, u64> r; + BitField<8, 1, u64> zl; + BitField<9, 1, u64> zr; + BitField<10, 1, u64> plus; + BitField<11, 1, u64> minus; // D-Pad - BitField<12, 1, u64_le> d_left; - BitField<13, 1, u64_le> d_up; - BitField<14, 1, u64_le> d_right; - BitField<15, 1, u64_le> d_down; + BitField<12, 1, u64> d_left; + BitField<13, 1, u64> d_up; + BitField<14, 1, u64> d_right; + BitField<15, 1, u64> d_down; // Left JoyStick - BitField<16, 1, u64_le> l_stick_left; - BitField<17, 1, u64_le> l_stick_up; - BitField<18, 1, u64_le> l_stick_right; - BitField<19, 1, u64_le> l_stick_down; + BitField<16, 1, u64> l_stick_left; + BitField<17, 1, u64> l_stick_up; + BitField<18, 1, u64> l_stick_right; + BitField<19, 1, u64> l_stick_down; // Right JoyStick - BitField<20, 1, u64_le> r_stick_left; - BitField<21, 1, u64_le> r_stick_up; - BitField<22, 1, u64_le> r_stick_right; - BitField<23, 1, u64_le> r_stick_down; + BitField<20, 1, u64> r_stick_left; + BitField<21, 1, u64> r_stick_up; + BitField<22, 1, u64> r_stick_right; + BitField<23, 1, u64> r_stick_down; // Not always active? - BitField<24, 1, u64_le> left_sl; - BitField<25, 1, u64_le> left_sr; + BitField<24, 1, u64> left_sl; + BitField<25, 1, u64> left_sr; - BitField<26, 1, u64_le> right_sl; - BitField<27, 1, u64_le> right_sr; + BitField<26, 1, u64> right_sl; + BitField<27, 1, u64> right_sr; }; }; static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size"); @@ -200,12 +200,12 @@ private: struct ConnectionState { union { u32_le raw{}; - BitField<0, 1, u32_le> IsConnected; - BitField<1, 1, u32_le> IsWired; - BitField<2, 1, u32_le> IsLeftJoyConnected; - BitField<3, 1, u32_le> IsLeftJoyWired; - BitField<4, 1, u32_le> IsRightJoyConnected; - BitField<5, 1, u32_le> IsRightJoyWired; + BitField<0, 1, u32> IsConnected; + BitField<1, 1, u32> IsWired; + BitField<2, 1, u32> IsLeftJoyConnected; + BitField<3, 1, u32> IsLeftJoyWired; + BitField<4, 1, u32> IsRightJoyConnected; + BitField<5, 1, u32> IsRightJoyWired; }; }; static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); @@ -240,23 +240,23 @@ private: struct NPadProperties { union { s64_le raw{}; - BitField<11, 1, s64_le> is_vertical; - BitField<12, 1, s64_le> is_horizontal; - BitField<13, 1, s64_le> use_plus; - BitField<14, 1, s64_le> use_minus; + BitField<11, 1, s64> is_vertical; + BitField<12, 1, s64> is_horizontal; + BitField<13, 1, s64> use_plus; + BitField<14, 1, s64> use_minus; }; }; struct NPadDevice { union { u32_le raw{}; - BitField<0, 1, s32_le> pro_controller; - BitField<1, 1, s32_le> handheld; - BitField<2, 1, s32_le> handheld_left; - BitField<3, 1, s32_le> handheld_right; - BitField<4, 1, s32_le> joycon_left; - BitField<5, 1, s32_le> joycon_right; - BitField<6, 1, s32_le> pokeball; + BitField<0, 1, s32> pro_controller; + BitField<1, 1, s32> handheld; + BitField<2, 1, s32> handheld_left; + BitField<3, 1, s32> handheld_right; + BitField<4, 1, s32> joycon_left; + BitField<5, 1, s32> joycon_right; + BitField<6, 1, s32> pokeball; }; }; diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 012b6e0dd..76fc340e9 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h @@ -33,8 +33,8 @@ private: struct Attributes { union { u32 raw{}; - BitField<0, 1, u32_le> start_touch; - BitField<1, 1, u32_le> end_touch; + BitField<0, 1, u32> start_touch; + BitField<1, 1, u32> end_touch; }; }; static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size"); diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 7cc58db4c..498602de5 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -4,6 +4,9 @@ #pragma once +#include "core/hle/service/hid/controllers/controller_base.h" +#include "core/hle/service/service.h" + #include "controllers/controller_base.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 9df7ac50f..d65693fc7 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -319,15 +319,14 @@ public: } ASSERT(vm_manager - .MirrorMemory(*map_address, nro_addr, nro_size, - Kernel::MemoryState::ModuleCodeStatic) + .MirrorMemory(*map_address, nro_addr, nro_size, Kernel::MemoryState::ModuleCode) .IsSuccess()); ASSERT(vm_manager.UnmapRange(nro_addr, nro_size).IsSuccess()); if (bss_size > 0) { ASSERT(vm_manager .MirrorMemory(*map_address + nro_size, bss_addr, bss_size, - Kernel::MemoryState::ModuleCodeStatic) + Kernel::MemoryState::ModuleCode) .IsSuccess()); ASSERT(vm_manager.UnmapRange(bss_addr, bss_size).IsSuccess()); } @@ -388,8 +387,7 @@ public: const auto& nro_size = iter->second.size; ASSERT(vm_manager - .MirrorMemory(heap_addr, mapped_addr, nro_size, - Kernel::MemoryState::ModuleCodeStatic) + .MirrorMemory(heap_addr, mapped_addr, nro_size, Kernel::MemoryState::ModuleCode) .IsSuccess()); ASSERT(vm_manager.UnmapRange(mapped_addr, nro_size).IsSuccess()); diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index 1f462e087..2a61593e2 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -42,7 +42,7 @@ private: union { BitField<0, 16, Flags> flags; BitField<16, 8, Severity> severity; - BitField<24, 8, u32_le> verbosity; + BitField<24, 8, u32> verbosity; }; u32_le payload_size; diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index 0f02a1a18..4f6042b00 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h @@ -19,11 +19,11 @@ public: virtual ~nvdevice() = default; union Ioctl { u32_le raw; - BitField<0, 8, u32_le> cmd; - BitField<8, 8, u32_le> group; - BitField<16, 14, u32_le> length; - BitField<30, 1, u32_le> is_in; - BitField<31, 1, u32_le> is_out; + BitField<0, 8, u32> cmd; + BitField<8, 8, u32> group; + BitField<16, 14, u32> length; + BitField<30, 1, u32> is_in; + BitField<31, 1, u32> is_out; }; /** diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index a34b9e753..af62d33d2 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -10,6 +10,7 @@ #include "core/core.h" #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" #include "core/hle/service/nvdrv/devices/nvmap.h" +#include "core/memory.h" #include "video_core/memory_manager.h" #include "video_core/rasterizer_interface.h" #include "video_core/renderer_base.h" @@ -88,7 +89,7 @@ u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) for (const auto& entry : entries) { LOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}", entry.offset, entry.nvmap_handle, entry.pages); - Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10; + GPUVAddr offset = static_cast<GPUVAddr>(entry.offset) << 0x10; auto object = nvmap_dev->GetObject(entry.nvmap_handle); if (!object) { LOG_CRITICAL(Service_NVDRV, "nvmap {} is an invalid handle!", entry.nvmap_handle); @@ -101,7 +102,7 @@ u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) u64 size = static_cast<u64>(entry.pages) << 0x10; ASSERT(size <= object->size); - Tegra::GPUVAddr returned = gpu.MemoryManager().MapBufferEx(object->addr, offset, size); + GPUVAddr returned = gpu.MemoryManager().MapBufferEx(object->addr, offset, size); ASSERT(returned == offset); } std::memcpy(output.data(), entries.data(), output.size()); @@ -172,16 +173,8 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou return 0; } - auto& system_instance = Core::System::GetInstance(); - - // Remove this memory region from the rasterizer cache. - auto& gpu = system_instance.GPU(); - auto cpu_addr = gpu.MemoryManager().GpuToCpuAddress(params.offset); - ASSERT(cpu_addr); - gpu.FlushAndInvalidateRegion(*cpu_addr, itr->second.size); - - params.offset = gpu.MemoryManager().UnmapBuffer(params.offset, itr->second.size); - + params.offset = Core::System::GetInstance().GPU().MemoryManager().UnmapBuffer(params.offset, + itr->second.size); buffer_mappings.erase(itr->second.offset); std::memcpy(output.data(), ¶ms, output.size()); diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 117f87a45..00806b0ed 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -11,7 +11,6 @@ #include "core/hle/ipc.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/client_port.h" -#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/server_port.h" @@ -76,7 +75,8 @@ namespace Service { * Creates a function string for logging, complete with the name (or header code, depending * on what's passed in) the port name, and all the cmd_buff arguments. */ -[[maybe_unused]] static std::string MakeFunctionString(const char* name, const char* port_name, +[[maybe_unused]] static std::string MakeFunctionString(std::string_view name, + std::string_view port_name, const u32* cmd_buff) { // Number of params == bits 0-5 + bits 6-11 int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); @@ -158,9 +158,7 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) { return ReportUnimplementedFunction(ctx, info); } - LOG_TRACE( - Service, "{}", - MakeFunctionString(info->name, GetServiceName().c_str(), ctx.CommandBuffer()).c_str()); + LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName(), ctx.CommandBuffer())); handler_invoker(this, info->handler_callback, ctx); } @@ -169,7 +167,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co case IPC::CommandType::Close: { IPC::ResponseBuilder rb{context, 2}; rb.Push(RESULT_SUCCESS); - return ResultCode(ErrorModule::HIPC, ErrorDescription::RemoteProcessDead); + return IPC::ERR_REMOTE_PROCESS_DEAD; } case IPC::CommandType::ControlWithContext: case IPC::CommandType::Control: { diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index bef25433e..b9d6381b4 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -67,7 +67,7 @@ public: if (port == nullptr) { return nullptr; } - return std::static_pointer_cast<T>(port->hle_handler); + return std::static_pointer_cast<T>(port->GetHLEHandler()); } void InvokeControlRequest(Kernel::HLERequestContext& context); diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index a975767bb..566cd6006 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -24,6 +24,7 @@ #include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/nvflinger/buffer_queue.h" #include "core/hle/service/nvflinger/nvflinger.h" +#include "core/hle/service/service.h" #include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi_m.h" #include "core/hle/service/vi/vi_s.h" @@ -33,6 +34,7 @@ namespace Service::VI { constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::VI, 1}; +constexpr ResultCode ERR_PERMISSION_DENIED{ErrorModule::VI, 5}; constexpr ResultCode ERR_UNSUPPORTED{ErrorModule::VI, 6}; constexpr ResultCode ERR_NOT_FOUND{ErrorModule::VI, 7}; @@ -1203,26 +1205,40 @@ IApplicationDisplayService::IApplicationDisplayService( RegisterHandlers(functions); } -Module::Interface::Interface(std::shared_ptr<Module> module, const char* name, - std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) - : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {} +static bool IsValidServiceAccess(Permission permission, Policy policy) { + if (permission == Permission::User) { + return policy == Policy::User; + } + + if (permission == Permission::System || permission == Permission::Manager) { + return policy == Policy::User || policy == Policy::Compositor; + } -Module::Interface::~Interface() = default; + return false; +} -void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_VI, "(STUBBED) called"); +void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, + std::shared_ptr<NVFlinger::NVFlinger> nv_flinger, + Permission permission) { + IPC::RequestParser rp{ctx}; + const auto policy = rp.PopEnum<Policy>(); + + if (!IsValidServiceAccess(permission, policy)) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_PERMISSION_DENIED); + return; + } IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IApplicationDisplayService>(nv_flinger); + rb.PushIpcInterface<IApplicationDisplayService>(std::move(nv_flinger)); } void InstallInterfaces(SM::ServiceManager& service_manager, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) { - auto module = std::make_shared<Module>(); - std::make_shared<VI_M>(module, nv_flinger)->InstallAsService(service_manager); - std::make_shared<VI_S>(module, nv_flinger)->InstallAsService(service_manager); - std::make_shared<VI_U>(module, nv_flinger)->InstallAsService(service_manager); + std::make_shared<VI_M>(nv_flinger)->InstallAsService(service_manager); + std::make_shared<VI_S>(nv_flinger)->InstallAsService(service_manager); + std::make_shared<VI_U>(nv_flinger)->InstallAsService(service_manager); } } // namespace Service::VI diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h index e3963502a..6b66f8b81 100644 --- a/src/core/hle/service/vi/vi.h +++ b/src/core/hle/service/vi/vi.h @@ -4,12 +4,21 @@ #pragma once -#include "core/hle/service/service.h" +#include <memory> +#include "common/common_types.h" + +namespace Kernel { +class HLERequestContext; +} namespace Service::NVFlinger { class NVFlinger; } +namespace Service::SM { +class ServiceManager; +} + namespace Service::VI { enum class DisplayResolution : u32 { @@ -19,22 +28,25 @@ enum class DisplayResolution : u32 { UndockedHeight = 720, }; -class Module final { -public: - class Interface : public ServiceFramework<Interface> { - public: - explicit Interface(std::shared_ptr<Module> module, const char* name, - std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); - ~Interface() override; - - void GetDisplayService(Kernel::HLERequestContext& ctx); +/// Permission level for a particular VI service instance +enum class Permission { + User, + System, + Manager, +}; - protected: - std::shared_ptr<Module> module; - std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; - }; +/// A policy type that may be requested via GetDisplayService and +/// GetDisplayServiceWithProxyNameExchange +enum class Policy { + User, + Compositor, }; +namespace detail { +void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, + std::shared_ptr<NVFlinger::NVFlinger> nv_flinger, Permission permission); +} // namespace detail + /// Registers all VI services with the specified service manager. void InstallInterfaces(SM::ServiceManager& service_manager, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); diff --git a/src/core/hle/service/vi/vi_m.cpp b/src/core/hle/service/vi/vi_m.cpp index 207c06b16..06070087f 100644 --- a/src/core/hle/service/vi/vi_m.cpp +++ b/src/core/hle/service/vi/vi_m.cpp @@ -2,12 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" +#include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi_m.h" namespace Service::VI { -VI_M::VI_M(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) - : Module::Interface(std::move(module), "vi:m", std::move(nv_flinger)) { +VI_M::VI_M(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) + : ServiceFramework{"vi:m"}, nv_flinger{std::move(nv_flinger)} { static const FunctionInfo functions[] = { {2, &VI_M::GetDisplayService, "GetDisplayService"}, {3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, @@ -17,4 +19,10 @@ VI_M::VI_M(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> VI_M::~VI_M() = default; +void VI_M::GetDisplayService(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_VI, "called"); + + detail::GetDisplayServiceImpl(ctx, nv_flinger, Permission::Manager); +} + } // namespace Service::VI diff --git a/src/core/hle/service/vi/vi_m.h b/src/core/hle/service/vi/vi_m.h index 487d58d50..290e06689 100644 --- a/src/core/hle/service/vi/vi_m.h +++ b/src/core/hle/service/vi/vi_m.h @@ -4,14 +4,27 @@ #pragma once -#include "core/hle/service/vi/vi.h" +#include "core/hle/service/service.h" + +namespace Kernel { +class HLERequestContext; +} + +namespace Service::NVFlinger { +class NVFlinger; +} namespace Service::VI { -class VI_M final : public Module::Interface { +class VI_M final : public ServiceFramework<VI_M> { public: - explicit VI_M(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); + explicit VI_M(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); ~VI_M() override; + +private: + void GetDisplayService(Kernel::HLERequestContext& ctx); + + std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; }; } // namespace Service::VI diff --git a/src/core/hle/service/vi/vi_s.cpp b/src/core/hle/service/vi/vi_s.cpp index 920e6a1f6..57c596cc4 100644 --- a/src/core/hle/service/vi/vi_s.cpp +++ b/src/core/hle/service/vi/vi_s.cpp @@ -2,12 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" +#include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi_s.h" namespace Service::VI { -VI_S::VI_S(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) - : Module::Interface(std::move(module), "vi:s", std::move(nv_flinger)) { +VI_S::VI_S(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) + : ServiceFramework{"vi:s"}, nv_flinger{std::move(nv_flinger)} { static const FunctionInfo functions[] = { {1, &VI_S::GetDisplayService, "GetDisplayService"}, {3, nullptr, "GetDisplayServiceWithProxyNameExchange"}, @@ -17,4 +19,10 @@ VI_S::VI_S(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> VI_S::~VI_S() = default; +void VI_S::GetDisplayService(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_VI, "called"); + + detail::GetDisplayServiceImpl(ctx, nv_flinger, Permission::System); +} + } // namespace Service::VI diff --git a/src/core/hle/service/vi/vi_s.h b/src/core/hle/service/vi/vi_s.h index bbc31148f..47804dc0b 100644 --- a/src/core/hle/service/vi/vi_s.h +++ b/src/core/hle/service/vi/vi_s.h @@ -4,14 +4,27 @@ #pragma once -#include "core/hle/service/vi/vi.h" +#include "core/hle/service/service.h" + +namespace Kernel { +class HLERequestContext; +} + +namespace Service::NVFlinger { +class NVFlinger; +} namespace Service::VI { -class VI_S final : public Module::Interface { +class VI_S final : public ServiceFramework<VI_S> { public: - explicit VI_S(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); + explicit VI_S(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); ~VI_S() override; + +private: + void GetDisplayService(Kernel::HLERequestContext& ctx); + + std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; }; } // namespace Service::VI diff --git a/src/core/hle/service/vi/vi_u.cpp b/src/core/hle/service/vi/vi_u.cpp index d81e410d6..9d5ceb608 100644 --- a/src/core/hle/service/vi/vi_u.cpp +++ b/src/core/hle/service/vi/vi_u.cpp @@ -2,12 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" +#include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi_u.h" namespace Service::VI { -VI_U::VI_U(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) - : Module::Interface(std::move(module), "vi:u", std::move(nv_flinger)) { +VI_U::VI_U(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) + : ServiceFramework{"vi:u"}, nv_flinger{std::move(nv_flinger)} { static const FunctionInfo functions[] = { {0, &VI_U::GetDisplayService, "GetDisplayService"}, }; @@ -16,4 +18,10 @@ VI_U::VI_U(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> VI_U::~VI_U() = default; +void VI_U::GetDisplayService(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_VI, "called"); + + detail::GetDisplayServiceImpl(ctx, nv_flinger, Permission::User); +} + } // namespace Service::VI diff --git a/src/core/hle/service/vi/vi_u.h b/src/core/hle/service/vi/vi_u.h index b92f28c92..19bdb73b0 100644 --- a/src/core/hle/service/vi/vi_u.h +++ b/src/core/hle/service/vi/vi_u.h @@ -4,14 +4,27 @@ #pragma once -#include "core/hle/service/vi/vi.h" +#include "core/hle/service/service.h" + +namespace Kernel { +class HLERequestContext; +} + +namespace Service::NVFlinger { +class NVFlinger; +} namespace Service::VI { -class VI_U final : public Module::Interface { +class VI_U final : public ServiceFramework<VI_U> { public: - explicit VI_U(std::shared_ptr<Module> module, std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); + explicit VI_U(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger); ~VI_U() override; + +private: + void GetDisplayService(Kernel::HLERequestContext& ctx); + + std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; }; } // namespace Service::VI |