mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-28 23:35:30 +03:00
Minor Audio Refactor (and fix sm:IUserManager
service name)
This makes some tiny changes to audio to make them compliant with the guidelines. In addition, to changing `IUserManager:IUserManager` to `sm:IUserManager`.
This commit is contained in:
parent
9f0ad46903
commit
d75d30b809
@ -53,7 +53,7 @@ add_library(skyline SHARED
|
||||
${source_DIR}/skyline/services/audio/IAudioRendererManager.cpp
|
||||
${source_DIR}/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp
|
||||
${source_DIR}/skyline/services/audio/IAudioRenderer/voice.cpp
|
||||
${source_DIR}/skyline/services/audio/IAudioRenderer/memoryPool.cpp
|
||||
${source_DIR}/skyline/services/audio/IAudioRenderer/memory_pool.cpp
|
||||
${source_DIR}/skyline/services/settings/ISystemSettingsServer.cpp
|
||||
${source_DIR}/skyline/services/apm/IManager.cpp
|
||||
${source_DIR}/skyline/services/apm/ISession.cpp
|
||||
|
@ -112,10 +112,10 @@ namespace skyline::audio {
|
||||
{-58, 4354, 26130, 2338}, {-54, 4199, 26169, 2451}, {-50, 4046, 26202, 2568}, {-46, 3897, 26230, 2688},
|
||||
{-42, 3751, 26253, 2811}, {-38, 3608, 26270, 2936}, {-34, 3467, 26281, 3064}, {-32, 3329, 26287, 3195}}};
|
||||
|
||||
std::vector<i16> Resampler::ResampleBuffer(std::vector<i16> &inputBuffer, double ratio, int channelCount) {
|
||||
uint step = static_cast<uint>(ratio * 0x8000);
|
||||
uint outputSize = static_cast<uint>(static_cast<double>(inputBuffer.size()) / ratio);
|
||||
std::vector<i16> outputBuffer(static_cast<size_t>(outputSize));
|
||||
std::vector<i16> Resampler::ResampleBuffer(const std::vector<i16> &inputBuffer, double ratio, int channelCount) {
|
||||
auto step = static_cast<uint>(ratio * 0x8000);
|
||||
auto outputSize = static_cast<size_t>(inputBuffer.size() / ratio);
|
||||
std::vector<i16> outputBuffer(outputSize);
|
||||
|
||||
const std::array<skyline::audio::LutEntry, 128> &lut = [step] {
|
||||
if (step > 0xaaaa)
|
||||
@ -126,20 +126,19 @@ namespace skyline::audio {
|
||||
return CurveLut2;
|
||||
}();
|
||||
|
||||
for (uint outIndex = 0, inIndex = 0; outIndex < outputBuffer.size(); outIndex += channelCount) {
|
||||
uint lutIndex = (fraction >> 8) << 2;
|
||||
for (auto outIndex = 0, inIndex = 0; outIndex < outputBuffer.size(); outIndex += channelCount) {
|
||||
auto lutIndex = (fraction >> 8) << 2;
|
||||
|
||||
for (int channel = 0; channel < channelCount; channel++) {
|
||||
int data = inputBuffer[(inIndex + 0) * channelCount + channel] * lut[lutIndex].a +
|
||||
i32 data = inputBuffer[(inIndex + 0) * channelCount + channel] * lut[lutIndex].a +
|
||||
inputBuffer[(inIndex + 1) * channelCount + channel] * lut[lutIndex].b +
|
||||
inputBuffer[(inIndex + 2) * channelCount + channel] * lut[lutIndex].c +
|
||||
inputBuffer[(inIndex + 3) * channelCount + channel] * lut[lutIndex].d;
|
||||
|
||||
outputBuffer[outIndex + channel] = static_cast<i16>(std::clamp(data >> 15,
|
||||
static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
|
||||
outputBuffer[outIndex + channel] = static_cast<i16>(std::clamp(data >> 15, static_cast<i32>(std::numeric_limits<i16>::min()), static_cast<i32>(std::numeric_limits<i16>::max())));
|
||||
}
|
||||
|
||||
uint newOffset = fraction + step;
|
||||
auto newOffset = fraction + step;
|
||||
inIndex += newOffset >> 15;
|
||||
fraction = newOffset & 0x7fff;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace skyline::audio {
|
||||
*/
|
||||
class Resampler {
|
||||
private:
|
||||
uint fraction{}; //!< The fractional value used for storing the resamplers last frame
|
||||
u32 fraction{}; //!< The fractional value used for storing the resamplers last frame
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -17,6 +17,6 @@ namespace skyline::audio {
|
||||
* @param ratio The conversion ratio needed
|
||||
* @param channelCount The amount of channels the buffer contains
|
||||
*/
|
||||
std::vector<i16> ResampleBuffer(std::vector<i16> &inputBuffer, double ratio, int channelCount);
|
||||
std::vector<i16> ResampleBuffer(const std::vector<i16> &inputBuffer, double ratio, int channelCount);
|
||||
};
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace skyline::audio {
|
||||
std::vector<u64> AudioTrack::GetReleasedBuffers(u32 max) {
|
||||
std::vector<u64> bufferIds;
|
||||
|
||||
for (u32 i = 0; i < max; i++) {
|
||||
for (auto i = 0; i < max; i++) {
|
||||
if (!identifierQueue.back().released)
|
||||
break;
|
||||
bufferIds.push_back(identifierQueue.back().tag);
|
||||
@ -54,7 +54,7 @@ namespace skyline::audio {
|
||||
bufferLock.lock();
|
||||
|
||||
identifierQueue.push_front(identifier);
|
||||
for (auto &sample : sampleData)
|
||||
for (const auto &sample : sampleData)
|
||||
sampleQueue.push(sample);
|
||||
|
||||
bufferLock.unlock();
|
||||
|
@ -128,7 +128,7 @@ namespace skyline::kernel::type {
|
||||
pread64(memFd, destination, size, offset);
|
||||
}
|
||||
|
||||
void KProcess::WriteMemory(void *source, const u64 offset, const size_t size, const bool forceGuest) const {
|
||||
void KProcess::WriteMemory(const void *source, const u64 offset, const size_t size, const bool forceGuest) const {
|
||||
if (!forceGuest) {
|
||||
auto destination = GetHostAddress(offset);
|
||||
|
||||
@ -139,7 +139,7 @@ namespace skyline::kernel::type {
|
||||
}
|
||||
|
||||
struct iovec local{
|
||||
.iov_base = source,
|
||||
.iov_base = const_cast<void *>(source),
|
||||
.iov_len = size,
|
||||
};
|
||||
|
||||
|
@ -259,7 +259,7 @@ namespace skyline {
|
||||
* @param size The amount of memory to be written
|
||||
* @param forceGuest This flag forces the write to be performed in guest address space
|
||||
*/
|
||||
void WriteMemory(void *source, const u64 offset, const size_t size, const bool forceGuest = false) const;
|
||||
void WriteMemory(const void *source, const u64 offset, const size_t size, const bool forceGuest = false) const;
|
||||
|
||||
/**
|
||||
* @brief Copy one chunk to another in the guest's memory
|
||||
|
@ -40,7 +40,7 @@ namespace skyline::service::audio {
|
||||
u64 sampleSize;
|
||||
u64 sampleOffset;
|
||||
} data = state.process->GetObject<Data>(request.inputBuf.at(0).address);
|
||||
u64 tag = request.Pop<u64>();
|
||||
auto tag = request.Pop<u64>();
|
||||
|
||||
state.logger->Debug("IAudioOut: Appending buffer with address: 0x{:X}, size: 0x{:X}", data.sampleBufferPtr, data.sampleSize);
|
||||
|
||||
@ -57,9 +57,9 @@ namespace skyline::service::audio {
|
||||
}
|
||||
|
||||
void IAudioOut::GetReleasedAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
u32 maxCount = static_cast<u32>(request.outputBuf.at(0).size >> 3);
|
||||
auto maxCount = static_cast<u32>(request.outputBuf.at(0).size >> 3);
|
||||
std::vector<u64> releasedBuffers = track->GetReleasedBuffers(maxCount);
|
||||
u32 count = static_cast<u32>(releasedBuffers.size());
|
||||
auto count = static_cast<u32>(releasedBuffers.size());
|
||||
|
||||
// Fill rest of output buffer with zeros
|
||||
releasedBuffers.resize(maxCount, 0);
|
||||
@ -69,7 +69,7 @@ namespace skyline::service::audio {
|
||||
}
|
||||
|
||||
void IAudioOut::ContainsAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
u64 tag = request.Pop<u64>();
|
||||
auto tag = request.Pop<u64>();
|
||||
|
||||
response.Push(static_cast<u32>(track->ContainsBuffer(tag)));
|
||||
}
|
||||
|
@ -9,8 +9,7 @@ namespace skyline::service::audio {
|
||||
}) {}
|
||||
|
||||
void IAudioOutManager::ListAudioOuts(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
state.process->WriteMemory(reinterpret_cast<void *>(const_cast<char *>(constant::DefaultAudioOutName.data())),
|
||||
request.outputBuf.at(0).address, constant::DefaultAudioOutName.size());
|
||||
state.process->WriteMemory(reinterpret_cast<void *>(const_cast<char *>(constant::DefaultAudioOutName.data())), request.outputBuf.at(0).address, constant::DefaultAudioOutName.size());
|
||||
}
|
||||
|
||||
void IAudioOutManager::OpenAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
|
@ -47,7 +47,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
}
|
||||
|
||||
void IAudioRenderer::RequestUpdate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
u64 inputAddress = request.inputBuf.at(0).address;
|
||||
auto inputAddress = request.inputBuf.at(0).address;
|
||||
|
||||
auto inputHeader = state.process->GetObject<UpdateDataHeader>(inputAddress);
|
||||
revisionInfo.SetUserRevision(inputHeader.revision);
|
||||
@ -58,7 +58,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
state.process->ReadMemory(memoryPoolsIn.data(), inputAddress, memoryPoolCount * sizeof(MemoryPoolIn));
|
||||
inputAddress += inputHeader.memoryPoolSize;
|
||||
|
||||
for (int i = 0; i < memoryPoolsIn.size(); i++)
|
||||
for (auto i = 0; i < memoryPoolsIn.size(); i++)
|
||||
memoryPools[i].ProcessInput(memoryPoolsIn[i]);
|
||||
|
||||
inputAddress += inputHeader.voiceResourceSize;
|
||||
@ -66,13 +66,13 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
state.process->ReadMemory(voicesIn.data(), inputAddress, rendererParams.voiceCount * sizeof(VoiceIn));
|
||||
inputAddress += inputHeader.voiceSize;
|
||||
|
||||
for (int i = 0; i < voicesIn.size(); i++)
|
||||
for (auto i = 0; i < voicesIn.size(); i++)
|
||||
voices[i].ProcessInput(voicesIn[i]);
|
||||
|
||||
std::vector<EffectIn> effectsIn(rendererParams.effectCount);
|
||||
state.process->ReadMemory(effectsIn.data(), inputAddress, rendererParams.effectCount * sizeof(EffectIn));
|
||||
|
||||
for (int i = 0; i < effectsIn.size(); i++)
|
||||
for (auto i = 0; i < effectsIn.size(); i++)
|
||||
effects[i].ProcessInput(effectsIn[i]);
|
||||
|
||||
UpdateAudio();
|
||||
@ -105,24 +105,24 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
state.process->WriteMemory(outputHeader, outputAddress);
|
||||
outputAddress += sizeof(UpdateDataHeader);
|
||||
|
||||
for (auto &memoryPool : memoryPools) {
|
||||
for (const auto &memoryPool : memoryPools) {
|
||||
state.process->WriteMemory(memoryPool.output, outputAddress);
|
||||
outputAddress += sizeof(MemoryPoolOut);
|
||||
}
|
||||
|
||||
for (auto &voice : voices) {
|
||||
for (const auto &voice : voices) {
|
||||
state.process->WriteMemory(voice.output, outputAddress);
|
||||
outputAddress += sizeof(VoiceOut);
|
||||
}
|
||||
|
||||
for (auto &effect : effects) {
|
||||
for (const auto &effect : effects) {
|
||||
state.process->WriteMemory(effect.output, outputAddress);
|
||||
outputAddress += sizeof(EffectOut);
|
||||
}
|
||||
}
|
||||
|
||||
void IAudioRenderer::UpdateAudio() {
|
||||
std::vector<u64> released = track->GetReleasedBuffers(2);
|
||||
auto released = track->GetReleasedBuffers(2);
|
||||
|
||||
for (auto &tag : released) {
|
||||
MixFinalBuffer();
|
||||
@ -153,14 +153,11 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
|
||||
for (int i = voiceBufferOffset; i < voiceBufferOffset + voiceBufferSize; i++) {
|
||||
if (setIndex == bufferOffset) {
|
||||
sampleBuffer[bufferOffset] = static_cast<i16>(std::clamp(static_cast<int>(static_cast<float>(voiceSamples[i]) *
|
||||
voice.volume), static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
|
||||
sampleBuffer[bufferOffset] = static_cast<i16>(std::clamp(static_cast<int>(static_cast<float>(voiceSamples[i]) * voice.volume), static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
|
||||
|
||||
setIndex++;
|
||||
} else {
|
||||
sampleBuffer[bufferOffset] += static_cast<i16>(std::clamp(static_cast<int>(sampleBuffer[voiceSamples[i]]) +
|
||||
static_cast<int>(static_cast<float>(voiceSamples[i]) * voice.volume),
|
||||
static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
|
||||
sampleBuffer[bufferOffset] += static_cast<i16>(std::clamp(static_cast<int>(sampleBuffer[voiceSamples[i]]) + static_cast<int>(static_cast<float>(voiceSamples[i]) * voice.volume), static_cast<int>(std::numeric_limits<i16>::min()), static_cast<int>(std::numeric_limits<i16>::max())));
|
||||
}
|
||||
|
||||
bufferOffset++;
|
||||
|
@ -4,10 +4,10 @@
|
||||
#include <services/base_service.h>
|
||||
#include <services/serviceman.h>
|
||||
#include <audio.h>
|
||||
#include "memoryPool.h"
|
||||
#include "memory_pool.h"
|
||||
#include "effect.h"
|
||||
#include "voice.h"
|
||||
#include "revisionInfo.h"
|
||||
#include "revision_info.h"
|
||||
|
||||
namespace skyline {
|
||||
namespace constant {
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "memoryPool.h"
|
||||
#include "memory_pool.h"
|
||||
|
||||
namespace skyline::service::audio::IAudioRenderer {
|
||||
void MemoryPool::ProcessInput(const MemoryPoolIn &input) {
|
@ -41,7 +41,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
}
|
||||
|
||||
void Voice::UpdateBuffers() {
|
||||
WaveBuffer ¤tBuffer = waveBuffers.at(bufferIndex);
|
||||
const auto ¤tBuffer = waveBuffers.at(bufferIndex);
|
||||
|
||||
if (currentBuffer.size == 0)
|
||||
return;
|
||||
@ -49,7 +49,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
switch (pcmFormat) {
|
||||
case skyline::audio::PcmFormat::Int16:
|
||||
sampleBuffer.resize(currentBuffer.size / sizeof(i16));
|
||||
state.process->ReadMemory(sampleBuffer.data(), currentBuffer.position, currentBuffer.size);
|
||||
state.process->ReadMemory(sampleBuffer.data(), currentBuffer.address, currentBuffer.size);
|
||||
break;
|
||||
default:
|
||||
throw exception("Unsupported voice PCM format: {}", pcmFormat);
|
||||
@ -59,11 +59,11 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
sampleBuffer = resampler.ResampleBuffer(sampleBuffer, static_cast<double>(sampleRate) / constant::SampleRate, channelCount);
|
||||
|
||||
if (channelCount == 1 && constant::ChannelCount != channelCount) {
|
||||
size_t originalSize = sampleBuffer.size();
|
||||
auto originalSize = sampleBuffer.size();
|
||||
sampleBuffer.resize((originalSize / channelCount) * constant::ChannelCount);
|
||||
|
||||
for (size_t monoIndex = originalSize - 1, targetIndex = sampleBuffer.size(); monoIndex > 0; monoIndex--)
|
||||
for (uint i = 0; i < constant::ChannelCount; i++)
|
||||
for (auto monoIndex = originalSize - 1, targetIndex = sampleBuffer.size(); monoIndex > 0; monoIndex--)
|
||||
for (auto i = 0; i < constant::ChannelCount; i++)
|
||||
sampleBuffer[--targetIndex] = sampleBuffer[monoIndex];
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ namespace skyline::service::audio::IAudioRenderer {
|
||||
* @brief This stores information of a wave buffer of samples
|
||||
*/
|
||||
struct WaveBuffer {
|
||||
u64 position; //!< The position of the wave buffer in guest memory
|
||||
u64 address; //!< The address of the wave buffer in guest memory
|
||||
u64 size; //!< The size of the wave buffer
|
||||
u32 firstSampleOffset; //!< The offset of the first sample in the buffer
|
||||
u32 lastSampleOffset; //!< The offset of the last sample in the buffer
|
||||
|
@ -11,8 +11,7 @@ namespace skyline::service::audio {
|
||||
void IAudioRendererManager::OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
IAudioRenderer::AudioRendererParams params = request.Pop<IAudioRenderer::AudioRendererParams>();
|
||||
|
||||
state.logger->Debug("IAudioRendererManager: Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}",
|
||||
IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount);
|
||||
state.logger->Debug("IAudioRendererManager: Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}", IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount);
|
||||
|
||||
manager.RegisterService(std::make_shared<IAudioRenderer::IAudioRenderer>(state, manager, params), session, response);
|
||||
}
|
||||
@ -31,10 +30,7 @@ namespace skyline::service::audio {
|
||||
params.voiceCount * 0x3F0 +
|
||||
utils::AlignUp(totalMixCount * 8, 16) +
|
||||
utils::AlignUp(params.voiceCount * 8, 16) +
|
||||
utils::AlignUp(((params.sinkCount + params.subMixCount) * 0x3C0 + params.sampleCount * 4) * (params.mixBufferCount + 6), constant::BufferAlignment) +
|
||||
(params.sinkCount + params.subMixCount) * 0x2C0 +
|
||||
(params.effectCount + params.voiceCount * 4) * 0x30 +
|
||||
0x50;
|
||||
utils::AlignUp(((params.sinkCount + params.subMixCount) * 0x3C0 + params.sampleCount * 4) * (params.mixBufferCount + 6), constant::BufferAlignment) + (params.sinkCount + params.subMixCount) * 0x2C0 + (params.effectCount + params.voiceCount * 4) * 0x30 + 0x50;
|
||||
|
||||
if (revisionInfo.SplitterSupported()) {
|
||||
i32 nodeStateWorkSize = utils::AlignUp(totalMixCount, constant::BufferAlignment);
|
||||
@ -54,45 +50,27 @@ namespace skyline::service::audio {
|
||||
i64 splitterWorkSize = 0;
|
||||
|
||||
if (revisionInfo.SplitterSupported()) {
|
||||
splitterWorkSize += params.splitterDestinationDataCount * 0xE0 +
|
||||
params.splitterCount * 0x20;
|
||||
splitterWorkSize += params.splitterDestinationDataCount * 0xE0 + params.splitterCount * 0x20;
|
||||
|
||||
if (revisionInfo.SplitterBugFixed())
|
||||
splitterWorkSize += utils::AlignUp(4 * params.splitterDestinationDataCount, 16);
|
||||
}
|
||||
size = params.sinkCount * 0x170 +
|
||||
(params.sinkCount + params.subMixCount) * 0x280 +
|
||||
params.effectCount * 0x4C0 +
|
||||
((size + splitterWorkSize + 0x30 * params.effectCount + (4 * params.voiceCount) + 0x8F) & ~0x3Fl) +
|
||||
((params.voiceCount << 8) | 0x40);
|
||||
size = params.sinkCount * 0x170 + (params.sinkCount + params.subMixCount) * 0x280 + params.effectCount * 0x4C0 + ((size + splitterWorkSize + 0x30 * params.effectCount + (4 * params.voiceCount) + 0x8F) & ~0x3Fl) + ((params.voiceCount << 8) | 0x40);
|
||||
|
||||
if (params.performanceManagerCount > 0) {
|
||||
i64 performanceMetricsBufferSize;
|
||||
|
||||
if (revisionInfo.UsesPerformanceMetricDataFormatV2()) {
|
||||
performanceMetricsBufferSize = (params.voiceCount +
|
||||
params.effectCount +
|
||||
totalMixCount +
|
||||
params.sinkCount) + 0x990;
|
||||
performanceMetricsBufferSize = (params.voiceCount + params.effectCount + totalMixCount + params.sinkCount) + 0x990;
|
||||
} else {
|
||||
performanceMetricsBufferSize = ((static_cast<i64>((params.voiceCount +
|
||||
params.effectCount +
|
||||
totalMixCount +
|
||||
params.sinkCount)) << 32) >> 0x1C) + 0x658;
|
||||
performanceMetricsBufferSize = ((static_cast<i64>((params.voiceCount + params.effectCount + totalMixCount + params.sinkCount)) << 32) >> 0x1C) + 0x658;
|
||||
}
|
||||
|
||||
size += (performanceMetricsBufferSize * (params.performanceManagerCount + 1) + 0xFF) & ~0x3Fl;
|
||||
}
|
||||
|
||||
if (revisionInfo.VaradicCommandBufferSizeSupported()) {
|
||||
size += params.effectCount * 0x840 +
|
||||
params.subMixCount * 0x5A38 +
|
||||
params.sinkCount * 0x148 +
|
||||
params.splitterDestinationDataCount * 0x540 +
|
||||
(params.splitterCount * 0x68 + 0x2E0) * params.voiceCount +
|
||||
((params.voiceCount + params.subMixCount + params.effectCount + params.sinkCount + 0x65) << 6) +
|
||||
0x3F8 +
|
||||
0x7E;
|
||||
size += params.effectCount * 0x840 + params.subMixCount * 0x5A38 + params.sinkCount * 0x148 + params.splitterDestinationDataCount * 0x540 + (params.splitterCount * 0x68 + 0x2E0) * params.voiceCount + ((params.voiceCount + params.subMixCount + params.effectCount + params.sinkCount + 0x65) << 6) + 0x3F8 + 0x7E;
|
||||
} else {
|
||||
size += 0x1807E;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "IUserInterface.h"
|
||||
|
||||
namespace skyline::service::sm {
|
||||
IUserInterface::IUserInterface(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::sm_IUserInterface, "IUserInterface:IUserInterface", {
|
||||
IUserInterface::IUserInterface(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, Service::sm_IUserInterface, "sm:IUserInterface", {
|
||||
{0x0, SFUNC(IUserInterface::Initialize)},
|
||||
{0x1, SFUNC(IUserInterface::GetService)}
|
||||
}) {}
|
||||
|
Loading…
Reference in New Issue
Block a user