Compare commits
123 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
424bffcd3f | ||
|
|
16aadcc354 | ||
|
|
395997178b | ||
|
|
5842a767a9 | ||
|
|
774d7eab64 | ||
|
|
88089c8754 | ||
|
|
1ea6bdef05 | ||
|
|
9abb23cd27 | ||
|
|
25f650e075 | ||
|
|
d39dfdf45c | ||
|
|
ece0ae2bfb | ||
|
|
7b4a213603 | ||
|
|
44f7067cab | ||
|
|
756225c8ff | ||
|
|
7bc3e80399 | ||
|
|
63b3b25715 | ||
|
|
6750b4d3af | ||
|
|
6314ed5de0 | ||
|
|
4eb7327559 | ||
|
|
312a8bd4b4 | ||
|
|
e0d30fc920 | ||
|
|
d7019d8307 | ||
|
|
d9b729bbfd | ||
|
|
1fde40b2c7 | ||
|
|
fca87cfa3e | ||
|
|
32f3b6b865 | ||
|
|
3dc310bd52 | ||
|
|
1dbe39f7a2 | ||
|
|
5bc4eabe36 | ||
|
|
f397edff0e | ||
|
|
073e07ae2d | ||
|
|
ee5e77fbf9 | ||
|
|
3898d8f0d7 | ||
|
|
1a954b2a59 | ||
|
|
ab315011fb | ||
|
|
4681e1ea9e | ||
|
|
2ccf85a910 | ||
|
|
9d3d0ae999 | ||
|
|
979b602738 | ||
|
|
322349e8cc | ||
|
|
e46f0e084c | ||
|
|
ebcee03b0c | ||
|
|
2c2b586d86 | ||
|
|
c9e3abe206 | ||
|
|
630823e363 | ||
|
|
b70751ccb9 | ||
|
|
e48e9a406c | ||
|
|
0e15c68f54 | ||
|
|
eab041866b | ||
|
|
b834c21894 | ||
|
|
d52ee6d0a7 | ||
|
|
dcfa1992ea | ||
|
|
b7f1095980 | ||
|
|
6f70e1b1ff | ||
|
|
9aeada734d | ||
|
|
e87670ee48 | ||
|
|
1dbf71ceb3 | ||
|
|
9014861858 | ||
|
|
d1da7eb119 | ||
|
|
0832da3e40 | ||
|
|
3359e5ab70 | ||
|
|
4fbe4da911 | ||
|
|
4fb5ca80c0 | ||
|
|
5f75d97125 | ||
|
|
7791cc8c2e | ||
|
|
e8b2fd21d8 | ||
|
|
fbda5e9ec9 | ||
|
|
410ed82922 | ||
|
|
7afb7a9494 | ||
|
|
6694e11303 | ||
|
|
ab25d1fe9a | ||
|
|
5ec6a265bf | ||
|
|
7fb7540d69 | ||
|
|
d04abd39eb | ||
|
|
e371d12af6 | ||
|
|
994f497781 | ||
|
|
5d1447897a | ||
|
|
874be0e3e1 | ||
|
|
2b05c32343 | ||
|
|
b546640c41 | ||
|
|
5c4774e8ce | ||
|
|
3a85bc1e77 | ||
|
|
e13a91fa9b | ||
|
|
5502f39125 | ||
|
|
ba3dd7b78f | ||
|
|
afd0e2ee87 | ||
|
|
185bf3fd28 | ||
|
|
8758378dc4 | ||
|
|
102630f2b2 | ||
|
|
d88baa746b | ||
|
|
acc14d233f | ||
|
|
b00f4abe36 | ||
|
|
c47c3d723f | ||
|
|
3794c91145 | ||
|
|
01db5cf203 | ||
|
|
ba3916fc67 | ||
|
|
3fcc98e11a | ||
|
|
5b441fa25d | ||
|
|
8469b76630 | ||
|
|
715f0c3b0c | ||
|
|
bba7e8ea4b | ||
|
|
e883101999 | ||
|
|
1889b641d9 | ||
|
|
3f2e605dd1 | ||
|
|
6971d08893 | ||
|
|
6e37676482 | ||
|
|
5b6545b141 | ||
|
|
412044960a | ||
|
|
6f8a06bac5 | ||
|
|
aaf262bfed | ||
|
|
bcaadac22c | ||
|
|
be4fc777c0 | ||
|
|
908d3c5679 | ||
|
|
9a4beac95a | ||
|
|
622830f4e1 | ||
|
|
9ea8cffe35 | ||
|
|
f5110340e6 | ||
|
|
fc4d692c50 | ||
|
|
31c12de0fe | ||
|
|
70df449d0a | ||
|
|
43ce33b6cc | ||
|
|
24620bc4ea | ||
|
|
b178c9a349 |
@@ -5,7 +5,7 @@ cd /yuzu
|
||||
ccache -s
|
||||
|
||||
mkdir build || true && cd build
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON
|
||||
|
||||
ninja
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ parameters:
|
||||
version: ''
|
||||
|
||||
steps:
|
||||
- script: choco install vulkan-sdk
|
||||
displayName: 'Install vulkan-sdk'
|
||||
- script: python -m pip install --upgrade pip conan
|
||||
displayName: 'Install conan'
|
||||
- script: mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 --config Release -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_UNICORN=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cd ..
|
||||
- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 --config Release -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_UNICORN=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cd ..
|
||||
displayName: 'Configure CMake'
|
||||
- task: MSBuild@1
|
||||
displayName: 'Build'
|
||||
|
||||
@@ -66,6 +66,7 @@ else()
|
||||
-Wextra
|
||||
-Wmissing-declarations
|
||||
-Wno-attributes
|
||||
-Wno-invalid-offsetof
|
||||
-Wno-unused-parameter
|
||||
)
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ if (NOT MSVC)
|
||||
-Werror=implicit-fallthrough
|
||||
-Werror=reorder
|
||||
-Werror=sign-compare
|
||||
-Werror=shadow
|
||||
-Werror=unused-parameter
|
||||
-Werror=unused-variable
|
||||
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
|
||||
|
||||
@@ -31,8 +31,8 @@ Filter Filter::LowPass(double cutoff, double Q) {
|
||||
|
||||
Filter::Filter() : Filter(1.0, 0.0, 0.0, 1.0, 0.0, 0.0) {}
|
||||
|
||||
Filter::Filter(double a0, double a1, double a2, double b0, double b1, double b2)
|
||||
: a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {}
|
||||
Filter::Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_)
|
||||
: a1(a1_ / a0_), a2(a2_ / a0_), b0(b0_ / a0_), b1(b1_ / a0_), b2(b2_ / a0_) {}
|
||||
|
||||
void Filter::Process(std::vector<s16>& signal) {
|
||||
const std::size_t num_frames = signal.size() / 2;
|
||||
@@ -69,7 +69,7 @@ CascadingFilter CascadingFilter::LowPass(double cutoff, std::size_t cascade_size
|
||||
}
|
||||
|
||||
CascadingFilter::CascadingFilter() = default;
|
||||
CascadingFilter::CascadingFilter(std::vector<Filter> filters) : filters(std::move(filters)) {}
|
||||
CascadingFilter::CascadingFilter(std::vector<Filter> filters_) : filters(std::move(filters_)) {}
|
||||
|
||||
void CascadingFilter::Process(std::vector<s16>& signal) {
|
||||
for (auto& filter : filters) {
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
/// Passthrough filter.
|
||||
Filter();
|
||||
|
||||
Filter(double a0, double a1, double a2, double b0, double b1, double b2);
|
||||
Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_);
|
||||
|
||||
void Process(std::vector<s16>& signal);
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
/// Passthrough.
|
||||
CascadingFilter();
|
||||
|
||||
explicit CascadingFilter(std::vector<Filter> filters);
|
||||
explicit CascadingFilter(std::vector<Filter> filters_);
|
||||
|
||||
void Process(std::vector<s16>& signal);
|
||||
|
||||
|
||||
@@ -43,6 +43,10 @@ std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream,
|
||||
return stream->GetTagsAndReleaseBuffers(max_count);
|
||||
}
|
||||
|
||||
std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream) {
|
||||
return stream->GetTagsAndReleaseBuffers();
|
||||
}
|
||||
|
||||
void AudioOut::StartStream(StreamPtr stream) {
|
||||
stream->Play();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ public:
|
||||
/// Returns a vector of recently released buffers specified by tag for the specified stream
|
||||
std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, std::size_t max_count);
|
||||
|
||||
/// Returns a vector of all recently released buffers specified by tag for the specified stream
|
||||
std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream);
|
||||
|
||||
/// Starts an audio stream for playback
|
||||
void StartStream(StreamPtr stream);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "audio_core/audio_out.h"
|
||||
@@ -14,19 +15,71 @@
|
||||
#include "core/memory.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace {
|
||||
[[nodiscard]] static constexpr s16 ClampToS16(s32 value) {
|
||||
return static_cast<s16>(std::clamp(value, s32{std::numeric_limits<s16>::min()},
|
||||
s32{std::numeric_limits<s16>::max()}));
|
||||
}
|
||||
|
||||
[[nodiscard]] static constexpr s16 Mix2To1(s16 l_channel, s16 r_channel) {
|
||||
// Mix 50% from left and 50% from right channel
|
||||
constexpr float l_mix_amount = 50.0f / 100.0f;
|
||||
constexpr float r_mix_amount = 50.0f / 100.0f;
|
||||
return ClampToS16(static_cast<s32>((static_cast<float>(l_channel) * l_mix_amount) +
|
||||
(static_cast<float>(r_channel) * r_mix_amount)));
|
||||
}
|
||||
|
||||
[[nodiscard]] static constexpr std::tuple<s16, s16> Mix6To2(s16 fl_channel, s16 fr_channel,
|
||||
s16 fc_channel,
|
||||
[[maybe_unused]] s16 lf_channel,
|
||||
s16 bl_channel, s16 br_channel) {
|
||||
// Front channels are mixed 36.94%, Center channels are mixed to be 26.12% & the back channels
|
||||
// are mixed to be 36.94%
|
||||
|
||||
constexpr float front_mix_amount = 36.94f / 100.0f;
|
||||
constexpr float center_mix_amount = 26.12f / 100.0f;
|
||||
constexpr float back_mix_amount = 36.94f / 100.0f;
|
||||
|
||||
// Mix 50% from left and 50% from right channel
|
||||
const auto left = front_mix_amount * static_cast<float>(fl_channel) +
|
||||
center_mix_amount * static_cast<float>(fc_channel) +
|
||||
back_mix_amount * static_cast<float>(bl_channel);
|
||||
|
||||
const auto right = front_mix_amount * static_cast<float>(fr_channel) +
|
||||
center_mix_amount * static_cast<float>(fc_channel) +
|
||||
back_mix_amount * static_cast<float>(br_channel);
|
||||
|
||||
return {ClampToS16(static_cast<s32>(left)), ClampToS16(static_cast<s32>(right))};
|
||||
}
|
||||
|
||||
[[nodiscard]] static constexpr std::tuple<s16, s16> Mix6To2WithCoefficients(
|
||||
s16 fl_channel, s16 fr_channel, s16 fc_channel, s16 lf_channel, s16 bl_channel, s16 br_channel,
|
||||
const std::array<float_le, 4>& coeff) {
|
||||
const auto left =
|
||||
static_cast<float>(fl_channel) * coeff[0] + static_cast<float>(fc_channel) * coeff[1] +
|
||||
static_cast<float>(lf_channel) * coeff[2] + static_cast<float>(bl_channel) * coeff[0];
|
||||
|
||||
const auto right =
|
||||
static_cast<float>(fr_channel) * coeff[0] + static_cast<float>(fc_channel) * coeff[1] +
|
||||
static_cast<float>(lf_channel) * coeff[2] + static_cast<float>(br_channel) * coeff[0];
|
||||
|
||||
return {ClampToS16(static_cast<s32>(left)), ClampToS16(static_cast<s32>(right))};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace AudioCore {
|
||||
AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
|
||||
AudioCommon::AudioRendererParameter params,
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event,
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event_,
|
||||
std::size_t instance_number)
|
||||
: worker_params{params}, buffer_event{buffer_event},
|
||||
: worker_params{params}, buffer_event{buffer_event_},
|
||||
memory_pool_info(params.effect_count + params.voice_count * 4),
|
||||
voice_context(params.voice_count), effect_context(params.effect_count), mix_context(),
|
||||
sink_context(params.sink_count), splitter_context(),
|
||||
voices(params.voice_count), memory{memory_},
|
||||
command_generator(worker_params, voice_context, mix_context, splitter_context, effect_context,
|
||||
memory),
|
||||
temp_mix_buffer(AudioCommon::TOTAL_TEMP_MIX_SIZE) {
|
||||
memory) {
|
||||
behavior_info.SetUserRevision(params.revision);
|
||||
splitter_context.Initialize(behavior_info, params.splitter_count,
|
||||
params.num_splitter_send_channels);
|
||||
@@ -35,7 +88,7 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory
|
||||
stream =
|
||||
audio_out->OpenStream(core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS,
|
||||
fmt::format("AudioRenderer-Instance{}", instance_number),
|
||||
[=]() { buffer_event->Signal(); });
|
||||
[=]() { buffer_event_->Signal(); });
|
||||
audio_out->StartStream(stream);
|
||||
|
||||
QueueMixedBuffer(0);
|
||||
@@ -62,10 +115,6 @@ Stream::State AudioRenderer::GetStreamState() const {
|
||||
return stream->GetState();
|
||||
}
|
||||
|
||||
static constexpr s16 ClampToS16(s32 value) {
|
||||
return static_cast<s16>(std::clamp(value, -32768, 32767));
|
||||
}
|
||||
|
||||
ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params,
|
||||
std::vector<u8>& output_params) {
|
||||
|
||||
@@ -104,8 +153,8 @@ ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_param
|
||||
}
|
||||
}
|
||||
|
||||
auto mix_result = info_updater.UpdateMixes(mix_context, worker_params.mix_buffer_count,
|
||||
splitter_context, effect_context);
|
||||
const auto mix_result = info_updater.UpdateMixes(mix_context, worker_params.mix_buffer_count,
|
||||
splitter_context, effect_context);
|
||||
|
||||
if (mix_result.IsError()) {
|
||||
LOG_ERROR(Audio, "Failed to update mix parameters");
|
||||
@@ -194,20 +243,22 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
|
||||
for (std::size_t i = 0; i < BUFFER_SIZE; i++) {
|
||||
if (channel_count == 1) {
|
||||
const auto sample = ClampToS16(mix_buffers[0][i]);
|
||||
buffer[i * stream_channel_count + 0] = sample;
|
||||
if (stream_channel_count > 1) {
|
||||
buffer[i * stream_channel_count + 1] = sample;
|
||||
|
||||
// Place sample in all channels
|
||||
for (u32 channel = 0; channel < stream_channel_count; channel++) {
|
||||
buffer[i * stream_channel_count + channel] = sample;
|
||||
}
|
||||
|
||||
if (stream_channel_count == 6) {
|
||||
buffer[i * stream_channel_count + 2] = sample;
|
||||
buffer[i * stream_channel_count + 4] = sample;
|
||||
buffer[i * stream_channel_count + 5] = sample;
|
||||
// Output stream has a LF channel, mute it!
|
||||
buffer[i * stream_channel_count + 3] = 0;
|
||||
}
|
||||
|
||||
} else if (channel_count == 2) {
|
||||
const auto l_sample = ClampToS16(mix_buffers[0][i]);
|
||||
const auto r_sample = ClampToS16(mix_buffers[1][i]);
|
||||
if (stream_channel_count == 1) {
|
||||
buffer[i * stream_channel_count + 0] = l_sample;
|
||||
buffer[i * stream_channel_count + 0] = Mix2To1(l_sample, r_sample);
|
||||
} else if (stream_channel_count == 2) {
|
||||
buffer[i * stream_channel_count + 0] = l_sample;
|
||||
buffer[i * stream_channel_count + 1] = r_sample;
|
||||
@@ -215,8 +266,8 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
|
||||
buffer[i * stream_channel_count + 0] = l_sample;
|
||||
buffer[i * stream_channel_count + 1] = r_sample;
|
||||
|
||||
buffer[i * stream_channel_count + 2] =
|
||||
ClampToS16((static_cast<s32>(l_sample) + static_cast<s32>(r_sample)) / 2);
|
||||
// Combine both left and right channels to the center channel
|
||||
buffer[i * stream_channel_count + 2] = Mix2To1(l_sample, r_sample);
|
||||
|
||||
buffer[i * stream_channel_count + 4] = l_sample;
|
||||
buffer[i * stream_channel_count + 5] = r_sample;
|
||||
@@ -231,17 +282,25 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
|
||||
const auto br_sample = ClampToS16(mix_buffers[5][i]);
|
||||
|
||||
if (stream_channel_count == 1) {
|
||||
buffer[i * stream_channel_count + 0] = fc_sample;
|
||||
// Games seem to ignore the center channel half the time, we use the front left
|
||||
// and right channel for mixing as that's where majority of the audio goes
|
||||
buffer[i * stream_channel_count + 0] = Mix2To1(fl_sample, fr_sample);
|
||||
} else if (stream_channel_count == 2) {
|
||||
buffer[i * stream_channel_count + 0] =
|
||||
static_cast<s16>(0.3694f * static_cast<float>(fl_sample) +
|
||||
0.2612f * static_cast<float>(fc_sample) +
|
||||
0.3694f * static_cast<float>(bl_sample));
|
||||
buffer[i * stream_channel_count + 1] =
|
||||
static_cast<s16>(0.3694f * static_cast<float>(fr_sample) +
|
||||
0.2612f * static_cast<float>(fc_sample) +
|
||||
0.3694f * static_cast<float>(br_sample));
|
||||
// Mix all channels into 2 channels
|
||||
if (sink_context.HasDownMixingCoefficients()) {
|
||||
const auto [left, right] = Mix6To2WithCoefficients(
|
||||
fl_sample, fr_sample, fc_sample, lf_sample, bl_sample, br_sample,
|
||||
sink_context.GetDownmixCoefficients());
|
||||
buffer[i * stream_channel_count + 0] = left;
|
||||
buffer[i * stream_channel_count + 1] = right;
|
||||
} else {
|
||||
const auto [left, right] = Mix6To2(fl_sample, fr_sample, fc_sample,
|
||||
lf_sample, bl_sample, br_sample);
|
||||
buffer[i * stream_channel_count + 0] = left;
|
||||
buffer[i * stream_channel_count + 1] = right;
|
||||
}
|
||||
} else if (stream_channel_count == 6) {
|
||||
// Pass through
|
||||
buffer[i * stream_channel_count + 0] = fl_sample;
|
||||
buffer[i * stream_channel_count + 1] = fr_sample;
|
||||
buffer[i * stream_channel_count + 2] = fc_sample;
|
||||
@@ -259,7 +318,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
|
||||
}
|
||||
|
||||
void AudioRenderer::ReleaseAndQueueBuffers() {
|
||||
const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream, 2)};
|
||||
const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream)};
|
||||
for (const auto& tag : released_buffers) {
|
||||
QueueMixedBuffer(tag);
|
||||
}
|
||||
|
||||
@@ -36,31 +36,26 @@ class Memory;
|
||||
}
|
||||
|
||||
namespace AudioCore {
|
||||
using DSPStateHolder = std::array<VoiceState*, 6>;
|
||||
using DSPStateHolder = std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT>;
|
||||
|
||||
class AudioOut;
|
||||
|
||||
struct RendererInfo {
|
||||
u64_le elasped_frame_count{};
|
||||
INSERT_PADDING_WORDS(2);
|
||||
};
|
||||
static_assert(sizeof(RendererInfo) == 0x10, "RendererInfo is an invalid size");
|
||||
|
||||
class AudioRenderer {
|
||||
public:
|
||||
AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
|
||||
AudioCommon::AudioRendererParameter params,
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event, std::size_t instance_number);
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event_,
|
||||
std::size_t instance_number);
|
||||
~AudioRenderer();
|
||||
|
||||
ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params,
|
||||
std::vector<u8>& output_params);
|
||||
[[nodiscard]] ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params,
|
||||
std::vector<u8>& output_params);
|
||||
void QueueMixedBuffer(Buffer::Tag tag);
|
||||
void ReleaseAndQueueBuffers();
|
||||
u32 GetSampleRate() const;
|
||||
u32 GetSampleCount() const;
|
||||
u32 GetMixBufferCount() const;
|
||||
Stream::State GetStreamState() const;
|
||||
[[nodiscard]] u32 GetSampleRate() const;
|
||||
[[nodiscard]] u32 GetSampleCount() const;
|
||||
[[nodiscard]] u32 GetMixBufferCount() const;
|
||||
[[nodiscard]] Stream::State GetStreamState() const;
|
||||
|
||||
private:
|
||||
BehaviorInfo behavior_info{};
|
||||
@@ -79,7 +74,6 @@ private:
|
||||
Core::Memory::Memory& memory;
|
||||
CommandGenerator command_generator;
|
||||
std::size_t elapsed_frame_count{};
|
||||
std::vector<s32> temp_mix_buffer{};
|
||||
};
|
||||
|
||||
} // namespace AudioCore
|
||||
|
||||
@@ -43,22 +43,22 @@ public:
|
||||
void ClearError();
|
||||
void UpdateFlags(u64_le dest_flags);
|
||||
void SetUserRevision(u32_le revision);
|
||||
u32_le GetUserRevision() const;
|
||||
u32_le GetProcessRevision() const;
|
||||
[[nodiscard]] u32_le GetUserRevision() const;
|
||||
[[nodiscard]] u32_le GetProcessRevision() const;
|
||||
|
||||
bool IsAdpcmLoopContextBugFixed() const;
|
||||
bool IsSplitterSupported() const;
|
||||
bool IsLongSizePreDelaySupported() const;
|
||||
bool IsAudioRendererProcessingTimeLimit80PercentSupported() const;
|
||||
bool IsAudioRendererProcessingTimeLimit75PercentSupported() const;
|
||||
bool IsAudioRendererProcessingTimeLimit70PercentSupported() const;
|
||||
bool IsElapsedFrameCountSupported() const;
|
||||
bool IsMemoryPoolForceMappingEnabled() const;
|
||||
bool IsFlushVoiceWaveBuffersSupported() const;
|
||||
bool IsVoicePlayedSampleCountResetAtLoopPointSupported() const;
|
||||
bool IsVoicePitchAndSrcSkippedSupported() const;
|
||||
bool IsMixInParameterDirtyOnlyUpdateSupported() const;
|
||||
bool IsSplitterBugFixed() const;
|
||||
[[nodiscard]] bool IsAdpcmLoopContextBugFixed() const;
|
||||
[[nodiscard]] bool IsSplitterSupported() const;
|
||||
[[nodiscard]] bool IsLongSizePreDelaySupported() const;
|
||||
[[nodiscard]] bool IsAudioRendererProcessingTimeLimit80PercentSupported() const;
|
||||
[[nodiscard]] bool IsAudioRendererProcessingTimeLimit75PercentSupported() const;
|
||||
[[nodiscard]] bool IsAudioRendererProcessingTimeLimit70PercentSupported() const;
|
||||
[[nodiscard]] bool IsElapsedFrameCountSupported() const;
|
||||
[[nodiscard]] bool IsMemoryPoolForceMappingEnabled() const;
|
||||
[[nodiscard]] bool IsFlushVoiceWaveBuffersSupported() const;
|
||||
[[nodiscard]] bool IsVoicePlayedSampleCountResetAtLoopPointSupported() const;
|
||||
[[nodiscard]] bool IsVoicePitchAndSrcSkippedSupported() const;
|
||||
[[nodiscard]] bool IsMixInParameterDirtyOnlyUpdateSupported() const;
|
||||
[[nodiscard]] bool IsSplitterBugFixed() const;
|
||||
void CopyErrorInfo(OutParams& dst);
|
||||
|
||||
private:
|
||||
|
||||
@@ -18,7 +18,7 @@ class Buffer {
|
||||
public:
|
||||
using Tag = u64;
|
||||
|
||||
Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {}
|
||||
Buffer(Tag tag_, std::vector<s16>&& samples_) : tag{tag_}, samples{std::move(samples_)} {}
|
||||
|
||||
/// Returns the raw audio data for the buffer
|
||||
std::vector<s16>& GetSamples() {
|
||||
|
||||
@@ -67,12 +67,12 @@ s32 ApplyMixDepop(s32* output, s32 first_sample, s32 delta, s32 sample_count) {
|
||||
|
||||
} // namespace
|
||||
|
||||
CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params,
|
||||
VoiceContext& voice_context, MixContext& mix_context,
|
||||
SplitterContext& splitter_context, EffectContext& effect_context,
|
||||
Core::Memory::Memory& memory)
|
||||
: worker_params(worker_params), voice_context(voice_context), mix_context(mix_context),
|
||||
splitter_context(splitter_context), effect_context(effect_context), memory(memory),
|
||||
CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_,
|
||||
VoiceContext& voice_context_, MixContext& mix_context_,
|
||||
SplitterContext& splitter_context_,
|
||||
EffectContext& effect_context_, Core::Memory::Memory& memory_)
|
||||
: worker_params(worker_params_), voice_context(voice_context_), mix_context(mix_context_),
|
||||
splitter_context(splitter_context_), effect_context(effect_context_), memory(memory_),
|
||||
mix_buffer((worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT) *
|
||||
worker_params.sample_count),
|
||||
sample_buffer(MIX_BUFFER_SIZE),
|
||||
@@ -255,7 +255,8 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo
|
||||
|
||||
void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info,
|
||||
VoiceState& dsp_state,
|
||||
s32 mix_buffer_count, s32 channel) {
|
||||
[[maybe_unused]] s32 mix_buffer_count,
|
||||
[[maybe_unused]] s32 channel) {
|
||||
for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) {
|
||||
const auto& in_params = voice_info.GetInParams();
|
||||
auto& biquad_filter = in_params.biquad_filter[i];
|
||||
@@ -278,9 +279,12 @@ void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voic
|
||||
}
|
||||
}
|
||||
|
||||
void AudioCore::CommandGenerator::GenerateBiquadFilterCommand(
|
||||
s32 mix_buffer, const BiquadFilterParameter& params, std::array<s64, 2>& state,
|
||||
std::size_t input_offset, std::size_t output_offset, s32 sample_count, s32 node_id) {
|
||||
void CommandGenerator::GenerateBiquadFilterCommand([[maybe_unused]] s32 mix_buffer_id,
|
||||
const BiquadFilterParameter& params,
|
||||
std::array<s64, 2>& state,
|
||||
std::size_t input_offset,
|
||||
std::size_t output_offset, s32 sample_count,
|
||||
s32 node_id) {
|
||||
if (dumping_frame) {
|
||||
LOG_DEBUG(Audio,
|
||||
"(DSP_TRACE) GenerateBiquadFilterCommand node_id={}, "
|
||||
@@ -714,7 +718,8 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
|
||||
}
|
||||
|
||||
s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
|
||||
s32 sample_count, s32 channel, std::size_t mix_offset) {
|
||||
s32 sample_count, [[maybe_unused]] s32 channel,
|
||||
std::size_t mix_offset) {
|
||||
const auto& in_params = voice_info.GetInParams();
|
||||
const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
|
||||
if (wave_buffer.buffer_address == 0) {
|
||||
|
||||
@@ -25,10 +25,10 @@ using MixVolumeBuffer = std::array<float, AudioCommon::MAX_MIX_BUFFERS>;
|
||||
|
||||
class CommandGenerator {
|
||||
public:
|
||||
explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params,
|
||||
VoiceContext& voice_context, MixContext& mix_context,
|
||||
SplitterContext& splitter_context, EffectContext& effect_context,
|
||||
Core::Memory::Memory& memory);
|
||||
explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_,
|
||||
VoiceContext& voice_context_, MixContext& mix_context_,
|
||||
SplitterContext& splitter_context_, EffectContext& effect_context_,
|
||||
Core::Memory::Memory& memory_);
|
||||
~CommandGenerator();
|
||||
|
||||
void ClearMixBuffers();
|
||||
@@ -39,13 +39,13 @@ public:
|
||||
void PreCommand();
|
||||
void PostCommand();
|
||||
|
||||
s32* GetChannelMixBuffer(s32 channel);
|
||||
const s32* GetChannelMixBuffer(s32 channel) const;
|
||||
s32* GetMixBuffer(std::size_t index);
|
||||
const s32* GetMixBuffer(std::size_t index) const;
|
||||
std::size_t GetMixChannelBufferOffset(s32 channel) const;
|
||||
[[nodiscard]] s32* GetChannelMixBuffer(s32 channel);
|
||||
[[nodiscard]] const s32* GetChannelMixBuffer(s32 channel) const;
|
||||
[[nodiscard]] s32* GetMixBuffer(std::size_t index);
|
||||
[[nodiscard]] const s32* GetMixBuffer(std::size_t index) const;
|
||||
[[nodiscard]] std::size_t GetMixChannelBufferOffset(s32 channel) const;
|
||||
|
||||
std::size_t GetTotalMixBufferCount() const;
|
||||
[[nodiscard]] std::size_t GetTotalMixBufferCount() const;
|
||||
|
||||
private:
|
||||
void GenerateDataSourceCommand(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 channel);
|
||||
@@ -73,7 +73,7 @@ private:
|
||||
void GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, EffectBase* info, bool enabled);
|
||||
void GenerateBiquadFilterEffectCommand(s32 mix_buffer_offset, EffectBase* info, bool enabled);
|
||||
void GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* info, bool enabled);
|
||||
ServerSplitterDestinationData* GetDestinationData(s32 splitter_id, s32 index);
|
||||
[[nodiscard]] ServerSplitterDestinationData* GetDestinationData(s32 splitter_id, s32 index);
|
||||
|
||||
s32 WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u32 max_samples, const s32* data,
|
||||
u32 sample_count, u32 write_offset, u32 write_count);
|
||||
|
||||
@@ -22,7 +22,7 @@ constexpr std::size_t MAX_CHANNEL_COUNT = 6;
|
||||
constexpr std::size_t MAX_WAVE_BUFFERS = 4;
|
||||
constexpr std::size_t MAX_SAMPLE_HISTORY = 4;
|
||||
constexpr u32 STREAM_SAMPLE_RATE = 48000;
|
||||
constexpr u32 STREAM_NUM_CHANNELS = 6;
|
||||
constexpr u32 STREAM_NUM_CHANNELS = 2;
|
||||
constexpr s32 NO_SPLITTER = -1;
|
||||
constexpr s32 NO_MIX = 0x7fffffff;
|
||||
constexpr s32 NO_FINAL_MIX = std::numeric_limits<s32>::min();
|
||||
|
||||
@@ -21,10 +21,10 @@ namespace AudioCore {
|
||||
|
||||
class CubebSinkStream final : public SinkStream {
|
||||
public:
|
||||
CubebSinkStream(cubeb* ctx, u32 sample_rate, u32 num_channels_, cubeb_devid output_device,
|
||||
CubebSinkStream(cubeb* ctx_, u32 sample_rate, u32 num_channels_, cubeb_devid output_device,
|
||||
const std::string& name)
|
||||
: ctx{ctx}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate,
|
||||
num_channels} {
|
||||
: ctx{ctx_}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate,
|
||||
num_channels} {
|
||||
|
||||
cubeb_stream_params params{};
|
||||
params.rate = sample_rate;
|
||||
@@ -192,8 +192,9 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels,
|
||||
return *sink_streams.back();
|
||||
}
|
||||
|
||||
long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
|
||||
void* output_buffer, long num_frames) {
|
||||
long CubebSinkStream::DataCallback([[maybe_unused]] cubeb_stream* stream, void* user_data,
|
||||
[[maybe_unused]] const void* input_buffer, void* output_buffer,
|
||||
long num_frames) {
|
||||
auto* impl = static_cast<CubebSinkStream*>(user_data);
|
||||
auto* buffer = static_cast<u8*>(output_buffer);
|
||||
|
||||
@@ -236,7 +237,9 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
|
||||
return num_frames;
|
||||
}
|
||||
|
||||
void CubebSinkStream::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) {}
|
||||
void CubebSinkStream::StateCallback([[maybe_unused]] cubeb_stream* stream,
|
||||
[[maybe_unused]] void* user_data,
|
||||
[[maybe_unused]] cubeb_state state) {}
|
||||
|
||||
std::vector<std::string> ListCubebSinkDevices() {
|
||||
std::vector<std::string> device_list;
|
||||
|
||||
@@ -12,7 +12,7 @@ bool ValidChannelCountForEffect(s32 channel_count) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
EffectContext::EffectContext(std::size_t effect_count) : effect_count(effect_count) {
|
||||
EffectContext::EffectContext(std::size_t effect_count_) : effect_count(effect_count_) {
|
||||
effects.reserve(effect_count);
|
||||
std::generate_n(std::back_inserter(effects), effect_count,
|
||||
[] { return std::make_unique<EffectStubbed>(); });
|
||||
@@ -61,13 +61,13 @@ const EffectBase* EffectContext::GetInfo(std::size_t i) const {
|
||||
return effects.at(i).get();
|
||||
}
|
||||
|
||||
EffectStubbed::EffectStubbed() : EffectBase::EffectBase(EffectType::Invalid) {}
|
||||
EffectStubbed::EffectStubbed() : EffectBase(EffectType::Invalid) {}
|
||||
EffectStubbed::~EffectStubbed() = default;
|
||||
|
||||
void EffectStubbed::Update(EffectInfo::InParams& in_params) {}
|
||||
void EffectStubbed::Update([[maybe_unused]] EffectInfo::InParams& in_params) {}
|
||||
void EffectStubbed::UpdateForCommandGeneration() {}
|
||||
|
||||
EffectBase::EffectBase(EffectType effect_type) : effect_type(effect_type) {}
|
||||
EffectBase::EffectBase(EffectType effect_type_) : effect_type(effect_type_) {}
|
||||
EffectBase::~EffectBase() = default;
|
||||
|
||||
UsageState EffectBase::GetUsage() const {
|
||||
@@ -90,32 +90,32 @@ s32 EffectBase::GetProcessingOrder() const {
|
||||
return processing_order;
|
||||
}
|
||||
|
||||
EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric::EffectGeneric(EffectType::I3dl2Reverb) {}
|
||||
EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric(EffectType::I3dl2Reverb) {}
|
||||
EffectI3dl2Reverb::~EffectI3dl2Reverb() = default;
|
||||
|
||||
void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) {
|
||||
auto& internal_params = GetParams();
|
||||
auto& params = GetParams();
|
||||
const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data());
|
||||
if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
|
||||
UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto last_status = internal_params.status;
|
||||
const auto last_status = params.status;
|
||||
mix_id = in_params.mix_id;
|
||||
processing_order = in_params.processing_order;
|
||||
internal_params = *reverb_params;
|
||||
params = *reverb_params;
|
||||
if (!ValidChannelCountForEffect(reverb_params->channel_count)) {
|
||||
internal_params.channel_count = internal_params.max_channels;
|
||||
params.channel_count = params.max_channels;
|
||||
}
|
||||
enabled = in_params.is_enabled;
|
||||
if (last_status != ParameterStatus::Updated) {
|
||||
internal_params.status = last_status;
|
||||
params.status = last_status;
|
||||
}
|
||||
|
||||
if (in_params.is_new || skipped) {
|
||||
usage = UsageState::Initialized;
|
||||
internal_params.status = ParameterStatus::Initialized;
|
||||
params.status = ParameterStatus::Initialized;
|
||||
skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
|
||||
}
|
||||
}
|
||||
@@ -129,15 +129,15 @@ void EffectI3dl2Reverb::UpdateForCommandGeneration() {
|
||||
GetParams().status = ParameterStatus::Updated;
|
||||
}
|
||||
|
||||
EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric::EffectGeneric(EffectType::BiquadFilter) {}
|
||||
EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric(EffectType::BiquadFilter) {}
|
||||
EffectBiquadFilter::~EffectBiquadFilter() = default;
|
||||
|
||||
void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) {
|
||||
auto& internal_params = GetParams();
|
||||
auto& params = GetParams();
|
||||
const auto* biquad_params = reinterpret_cast<BiquadFilterParams*>(in_params.raw.data());
|
||||
mix_id = in_params.mix_id;
|
||||
processing_order = in_params.processing_order;
|
||||
internal_params = *biquad_params;
|
||||
params = *biquad_params;
|
||||
enabled = in_params.is_enabled;
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ void EffectBiquadFilter::UpdateForCommandGeneration() {
|
||||
GetParams().status = ParameterStatus::Updated;
|
||||
}
|
||||
|
||||
EffectAuxInfo::EffectAuxInfo() : EffectGeneric::EffectGeneric(EffectType::Aux) {}
|
||||
EffectAuxInfo::EffectAuxInfo() : EffectGeneric(EffectType::Aux) {}
|
||||
EffectAuxInfo::~EffectAuxInfo() = default;
|
||||
|
||||
void EffectAuxInfo::Update(EffectInfo::InParams& in_params) {
|
||||
@@ -200,32 +200,32 @@ VAddr EffectAuxInfo::GetRecvBuffer() const {
|
||||
return recv_buffer;
|
||||
}
|
||||
|
||||
EffectDelay::EffectDelay() : EffectGeneric::EffectGeneric(EffectType::Delay) {}
|
||||
EffectDelay::EffectDelay() : EffectGeneric(EffectType::Delay) {}
|
||||
EffectDelay::~EffectDelay() = default;
|
||||
|
||||
void EffectDelay::Update(EffectInfo::InParams& in_params) {
|
||||
const auto* delay_params = reinterpret_cast<DelayParams*>(in_params.raw.data());
|
||||
auto& internal_params = GetParams();
|
||||
auto& params = GetParams();
|
||||
if (!ValidChannelCountForEffect(delay_params->max_channels)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto last_status = internal_params.status;
|
||||
const auto last_status = params.status;
|
||||
mix_id = in_params.mix_id;
|
||||
processing_order = in_params.processing_order;
|
||||
internal_params = *delay_params;
|
||||
params = *delay_params;
|
||||
if (!ValidChannelCountForEffect(delay_params->channels)) {
|
||||
internal_params.channels = internal_params.max_channels;
|
||||
params.channels = params.max_channels;
|
||||
}
|
||||
enabled = in_params.is_enabled;
|
||||
|
||||
if (last_status != ParameterStatus::Updated) {
|
||||
internal_params.status = last_status;
|
||||
params.status = last_status;
|
||||
}
|
||||
|
||||
if (in_params.is_new || skipped) {
|
||||
usage = UsageState::Initialized;
|
||||
internal_params.status = ParameterStatus::Initialized;
|
||||
params.status = ParameterStatus::Initialized;
|
||||
skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
|
||||
}
|
||||
}
|
||||
@@ -239,7 +239,7 @@ void EffectDelay::UpdateForCommandGeneration() {
|
||||
GetParams().status = ParameterStatus::Updated;
|
||||
}
|
||||
|
||||
EffectBufferMixer::EffectBufferMixer() : EffectGeneric::EffectGeneric(EffectType::BufferMixer) {}
|
||||
EffectBufferMixer::EffectBufferMixer() : EffectGeneric(EffectType::BufferMixer) {}
|
||||
EffectBufferMixer::~EffectBufferMixer() = default;
|
||||
|
||||
void EffectBufferMixer::Update(EffectInfo::InParams& in_params) {
|
||||
@@ -257,32 +257,32 @@ void EffectBufferMixer::UpdateForCommandGeneration() {
|
||||
}
|
||||
}
|
||||
|
||||
EffectReverb::EffectReverb() : EffectGeneric::EffectGeneric(EffectType::Reverb) {}
|
||||
EffectReverb::EffectReverb() : EffectGeneric(EffectType::Reverb) {}
|
||||
EffectReverb::~EffectReverb() = default;
|
||||
|
||||
void EffectReverb::Update(EffectInfo::InParams& in_params) {
|
||||
const auto* reverb_params = reinterpret_cast<ReverbParams*>(in_params.raw.data());
|
||||
auto& internal_params = GetParams();
|
||||
auto& params = GetParams();
|
||||
if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto last_status = internal_params.status;
|
||||
const auto last_status = params.status;
|
||||
mix_id = in_params.mix_id;
|
||||
processing_order = in_params.processing_order;
|
||||
internal_params = *reverb_params;
|
||||
params = *reverb_params;
|
||||
if (!ValidChannelCountForEffect(reverb_params->channels)) {
|
||||
internal_params.channels = internal_params.max_channels;
|
||||
params.channels = params.max_channels;
|
||||
}
|
||||
enabled = in_params.is_enabled;
|
||||
|
||||
if (last_status != ParameterStatus::Updated) {
|
||||
internal_params.status = last_status;
|
||||
params.status = last_status;
|
||||
}
|
||||
|
||||
if (in_params.is_new || skipped) {
|
||||
usage = UsageState::Initialized;
|
||||
internal_params.status = ParameterStatus::Initialized;
|
||||
params.status = ParameterStatus::Initialized;
|
||||
skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,16 +184,16 @@ struct AuxAddress {
|
||||
|
||||
class EffectBase {
|
||||
public:
|
||||
explicit EffectBase(EffectType effect_type);
|
||||
explicit EffectBase(EffectType effect_type_);
|
||||
virtual ~EffectBase();
|
||||
|
||||
virtual void Update(EffectInfo::InParams& in_params) = 0;
|
||||
virtual void UpdateForCommandGeneration() = 0;
|
||||
UsageState GetUsage() const;
|
||||
EffectType GetType() const;
|
||||
bool IsEnabled() const;
|
||||
s32 GetMixID() const;
|
||||
s32 GetProcessingOrder() const;
|
||||
[[nodiscard]] UsageState GetUsage() const;
|
||||
[[nodiscard]] EffectType GetType() const;
|
||||
[[nodiscard]] bool IsEnabled() const;
|
||||
[[nodiscard]] s32 GetMixID() const;
|
||||
[[nodiscard]] s32 GetProcessingOrder() const;
|
||||
|
||||
protected:
|
||||
UsageState usage{UsageState::Invalid};
|
||||
@@ -206,7 +206,7 @@ protected:
|
||||
template <typename T>
|
||||
class EffectGeneric : public EffectBase {
|
||||
public:
|
||||
explicit EffectGeneric(EffectType effect_type) : EffectBase(effect_type) {}
|
||||
explicit EffectGeneric(EffectType effect_type_) : EffectBase(effect_type_) {}
|
||||
|
||||
T& GetParams() {
|
||||
return internal_params;
|
||||
@@ -257,10 +257,10 @@ public:
|
||||
|
||||
void Update(EffectInfo::InParams& in_params) override;
|
||||
void UpdateForCommandGeneration() override;
|
||||
VAddr GetSendInfo() const;
|
||||
VAddr GetSendBuffer() const;
|
||||
VAddr GetRecvInfo() const;
|
||||
VAddr GetRecvBuffer() const;
|
||||
[[nodiscard]] VAddr GetSendInfo() const;
|
||||
[[nodiscard]] VAddr GetSendBuffer() const;
|
||||
[[nodiscard]] VAddr GetRecvInfo() const;
|
||||
[[nodiscard]] VAddr GetRecvBuffer() const;
|
||||
|
||||
private:
|
||||
VAddr send_info{};
|
||||
@@ -306,13 +306,13 @@ private:
|
||||
|
||||
class EffectContext {
|
||||
public:
|
||||
explicit EffectContext(std::size_t effect_count);
|
||||
explicit EffectContext(std::size_t effect_count_);
|
||||
~EffectContext();
|
||||
|
||||
std::size_t GetCount() const;
|
||||
EffectBase* GetInfo(std::size_t i);
|
||||
EffectBase* RetargetEffect(std::size_t i, EffectType effect);
|
||||
const EffectBase* GetInfo(std::size_t i) const;
|
||||
[[nodiscard]] std::size_t GetCount() const;
|
||||
[[nodiscard]] EffectBase* GetInfo(std::size_t i);
|
||||
[[nodiscard]] EffectBase* RetargetEffect(std::size_t i, EffectType effect);
|
||||
[[nodiscard]] const EffectBase* GetInfo(std::size_t i) const;
|
||||
|
||||
private:
|
||||
std::size_t effect_count{};
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
InfoUpdater::InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params,
|
||||
BehaviorInfo& behavior_info)
|
||||
: in_params(in_params), out_params(out_params), behavior_info(behavior_info) {
|
||||
InfoUpdater::InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_,
|
||||
BehaviorInfo& behavior_info_)
|
||||
: in_params(in_params_), out_params(out_params_), behavior_info(behavior_info_) {
|
||||
ASSERT(
|
||||
AudioCommon::CanConsumeBuffer(in_params.size(), 0, sizeof(AudioCommon::UpdateDataHeader)));
|
||||
std::memcpy(&input_header, in_params.data(), sizeof(AudioCommon::UpdateDataHeader));
|
||||
@@ -135,8 +135,8 @@ bool InfoUpdater::UpdateVoiceChannelResources(VoiceContext& voice_context) {
|
||||
}
|
||||
|
||||
bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||
std::vector<ServerMemoryPoolInfo>& memory_pool_info,
|
||||
VAddr audio_codec_dsp_addr) {
|
||||
[[maybe_unused]] std::vector<ServerMemoryPoolInfo>& memory_pool_info,
|
||||
[[maybe_unused]] VAddr audio_codec_dsp_addr) {
|
||||
const auto voice_count = voice_context.GetVoiceCount();
|
||||
std::vector<VoiceInfo::InParams> voice_in(voice_count);
|
||||
std::vector<VoiceInfo::OutParams> voice_out(voice_count);
|
||||
@@ -165,28 +165,28 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||
|
||||
// Update our voices
|
||||
for (std::size_t i = 0; i < voice_count; i++) {
|
||||
auto& in_params = voice_in[i];
|
||||
const auto channel_count = static_cast<std::size_t>(in_params.channel_count);
|
||||
auto& voice_in_params = voice_in[i];
|
||||
const auto channel_count = static_cast<std::size_t>(voice_in_params.channel_count);
|
||||
// Skip if it's not currently in use
|
||||
if (!in_params.is_in_use) {
|
||||
if (!voice_in_params.is_in_use) {
|
||||
continue;
|
||||
}
|
||||
// Voice states for each channel
|
||||
std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{};
|
||||
ASSERT(static_cast<std::size_t>(in_params.id) < voice_count);
|
||||
ASSERT(static_cast<std::size_t>(voice_in_params.id) < voice_count);
|
||||
|
||||
// Grab our current voice info
|
||||
auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id));
|
||||
auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(voice_in_params.id));
|
||||
|
||||
ASSERT(channel_count <= AudioCommon::MAX_CHANNEL_COUNT);
|
||||
|
||||
// Get all our channel voice states
|
||||
for (std::size_t channel = 0; channel < channel_count; channel++) {
|
||||
voice_states[channel] =
|
||||
&voice_context.GetState(in_params.voice_channel_resource_ids[channel]);
|
||||
&voice_context.GetState(voice_in_params.voice_channel_resource_ids[channel]);
|
||||
}
|
||||
|
||||
if (in_params.is_new) {
|
||||
if (voice_in_params.is_new) {
|
||||
// Default our values for our voice
|
||||
voice_info.Initialize();
|
||||
if (channel_count == 0 || channel_count > AudioCommon::MAX_CHANNEL_COUNT) {
|
||||
@@ -200,12 +200,12 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||
}
|
||||
|
||||
// Update our voice
|
||||
voice_info.UpdateParameters(in_params, behavior_info);
|
||||
voice_info.UpdateParameters(voice_in_params, behavior_info);
|
||||
// TODO(ogniK): Handle mapping errors with behavior info based on in params response
|
||||
|
||||
// Update our wave buffers
|
||||
voice_info.UpdateWaveBuffers(in_params, voice_states, behavior_info);
|
||||
voice_info.WriteOutStatus(voice_out[i], in_params, voice_states);
|
||||
voice_info.UpdateWaveBuffers(voice_in_params, voice_states, behavior_info);
|
||||
voice_info.WriteOutStatus(voice_out[i], voice_in_params, voice_states);
|
||||
}
|
||||
|
||||
if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, voice_out_size)) {
|
||||
@@ -445,7 +445,7 @@ bool InfoUpdater::UpdatePerformanceBuffer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InfoUpdater::UpdateErrorInfo(BehaviorInfo& in_behavior_info) {
|
||||
bool InfoUpdater::UpdateErrorInfo([[maybe_unused]] BehaviorInfo& in_behavior_info) {
|
||||
const auto total_beahvior_info_out = sizeof(BehaviorInfo::OutParams);
|
||||
|
||||
if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, total_beahvior_info_out)) {
|
||||
|
||||
@@ -21,8 +21,8 @@ class SplitterContext;
|
||||
class InfoUpdater {
|
||||
public:
|
||||
// TODO(ogniK): Pass process handle when we support it
|
||||
InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params,
|
||||
BehaviorInfo& behavior_info);
|
||||
InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_,
|
||||
BehaviorInfo& behavior_info_);
|
||||
~InfoUpdater();
|
||||
|
||||
bool UpdateBehaviorInfo(BehaviorInfo& in_behavior_info);
|
||||
|
||||
@@ -10,11 +10,10 @@ namespace AudioCore {
|
||||
|
||||
ServerMemoryPoolInfo::ServerMemoryPoolInfo() = default;
|
||||
ServerMemoryPoolInfo::~ServerMemoryPoolInfo() = default;
|
||||
bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_params,
|
||||
ServerMemoryPoolInfo::OutParams& out_params) {
|
||||
|
||||
bool ServerMemoryPoolInfo::Update(const InParams& in_params, OutParams& out_params) {
|
||||
// Our state does not need to be changed
|
||||
if (in_params.state != ServerMemoryPoolInfo::State::RequestAttach &&
|
||||
in_params.state != ServerMemoryPoolInfo::State::RequestDetach) {
|
||||
if (in_params.state != State::RequestAttach && in_params.state != State::RequestDetach) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -32,11 +31,11 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_params.state == ServerMemoryPoolInfo::State::RequestAttach) {
|
||||
if (in_params.state == State::RequestAttach) {
|
||||
cpu_address = in_params.address;
|
||||
size = in_params.size;
|
||||
used = true;
|
||||
out_params.state = ServerMemoryPoolInfo::State::Attached;
|
||||
out_params.state = State::Attached;
|
||||
} else {
|
||||
// Unexpected address
|
||||
if (cpu_address != in_params.address) {
|
||||
@@ -54,7 +53,7 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param
|
||||
cpu_address = 0;
|
||||
size = 0;
|
||||
used = false;
|
||||
out_params.state = ServerMemoryPoolInfo::State::Detached;
|
||||
out_params.state = State::Detached;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -28,19 +28,18 @@ public:
|
||||
struct InParams {
|
||||
u64_le address{};
|
||||
u64_le size{};
|
||||
ServerMemoryPoolInfo::State state{};
|
||||
State state{};
|
||||
INSERT_PADDING_WORDS(3);
|
||||
};
|
||||
static_assert(sizeof(ServerMemoryPoolInfo::InParams) == 0x20, "InParams are an invalid size");
|
||||
static_assert(sizeof(InParams) == 0x20, "InParams are an invalid size");
|
||||
|
||||
struct OutParams {
|
||||
ServerMemoryPoolInfo::State state{};
|
||||
State state{};
|
||||
INSERT_PADDING_WORDS(3);
|
||||
};
|
||||
static_assert(sizeof(ServerMemoryPoolInfo::OutParams) == 0x10, "OutParams are an invalid size");
|
||||
static_assert(sizeof(OutParams) == 0x10, "OutParams are an invalid size");
|
||||
|
||||
bool Update(const ServerMemoryPoolInfo::InParams& in_params,
|
||||
ServerMemoryPoolInfo::OutParams& out_params);
|
||||
bool Update(const InParams& in_params, OutParams& out_params);
|
||||
|
||||
private:
|
||||
// There's another entry here which is the DSP address, however since we're not talking to the
|
||||
|
||||
@@ -62,17 +62,17 @@ public:
|
||||
ServerMixInfo();
|
||||
~ServerMixInfo();
|
||||
|
||||
const ServerMixInfo::InParams& GetInParams() const;
|
||||
ServerMixInfo::InParams& GetInParams();
|
||||
[[nodiscard]] const ServerMixInfo::InParams& GetInParams() const;
|
||||
[[nodiscard]] ServerMixInfo::InParams& GetInParams();
|
||||
|
||||
bool Update(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix_in,
|
||||
BehaviorInfo& behavior_info, SplitterContext& splitter_context,
|
||||
EffectContext& effect_context);
|
||||
bool HasAnyConnection() const;
|
||||
[[nodiscard]] bool HasAnyConnection() const;
|
||||
void Cleanup();
|
||||
void SetEffectCount(std::size_t count);
|
||||
void ResetEffectProcessingOrder();
|
||||
s32 GetEffectOrder(std::size_t i) const;
|
||||
[[nodiscard]] s32 GetEffectOrder(std::size_t i) const;
|
||||
|
||||
private:
|
||||
std::vector<s32> effect_processing_order;
|
||||
@@ -91,15 +91,15 @@ public:
|
||||
void SortInfo();
|
||||
bool TsortInfo(SplitterContext& splitter_context);
|
||||
|
||||
std::size_t GetCount() const;
|
||||
ServerMixInfo& GetInfo(std::size_t i);
|
||||
const ServerMixInfo& GetInfo(std::size_t i) const;
|
||||
ServerMixInfo& GetSortedInfo(std::size_t i);
|
||||
const ServerMixInfo& GetSortedInfo(std::size_t i) const;
|
||||
ServerMixInfo& GetFinalMixInfo();
|
||||
const ServerMixInfo& GetFinalMixInfo() const;
|
||||
EdgeMatrix& GetEdgeMatrix();
|
||||
const EdgeMatrix& GetEdgeMatrix() const;
|
||||
[[nodiscard]] std::size_t GetCount() const;
|
||||
[[nodiscard]] ServerMixInfo& GetInfo(std::size_t i);
|
||||
[[nodiscard]] const ServerMixInfo& GetInfo(std::size_t i) const;
|
||||
[[nodiscard]] ServerMixInfo& GetSortedInfo(std::size_t i);
|
||||
[[nodiscard]] const ServerMixInfo& GetSortedInfo(std::size_t i) const;
|
||||
[[nodiscard]] ServerMixInfo& GetFinalMixInfo();
|
||||
[[nodiscard]] const ServerMixInfo& GetFinalMixInfo() const;
|
||||
[[nodiscard]] EdgeMatrix& GetEdgeMatrix();
|
||||
[[nodiscard]] const EdgeMatrix& GetEdgeMatrix() const;
|
||||
|
||||
private:
|
||||
void CalcMixBufferOffset();
|
||||
|
||||
@@ -5,17 +5,23 @@
|
||||
#include "audio_core/sink_context.h"
|
||||
|
||||
namespace AudioCore {
|
||||
SinkContext::SinkContext(std::size_t sink_count) : sink_count(sink_count) {}
|
||||
SinkContext::SinkContext(std::size_t sink_count_) : sink_count{sink_count_} {}
|
||||
SinkContext::~SinkContext() = default;
|
||||
|
||||
std::size_t SinkContext::GetCount() const {
|
||||
return sink_count;
|
||||
}
|
||||
|
||||
void SinkContext::UpdateMainSink(SinkInfo::InParams& in) {
|
||||
void SinkContext::UpdateMainSink(const SinkInfo::InParams& in) {
|
||||
ASSERT(in.type == SinkTypes::Device);
|
||||
|
||||
has_downmix_coefs = in.device.down_matrix_enabled;
|
||||
if (has_downmix_coefs) {
|
||||
downmix_coefficients = in.device.down_matrix_coef;
|
||||
}
|
||||
in_use = in.in_use;
|
||||
use_count = in.device.input_count;
|
||||
std::memcpy(buffers.data(), in.device.input.data(), AudioCommon::MAX_CHANNEL_COUNT);
|
||||
buffers = in.device.input;
|
||||
}
|
||||
|
||||
bool SinkContext::InUse() const {
|
||||
@@ -28,4 +34,12 @@ std::vector<u8> SinkContext::OutputBuffers() const {
|
||||
return buffer_ret;
|
||||
}
|
||||
|
||||
bool SinkContext::HasDownMixingCoefficients() const {
|
||||
return has_downmix_coefs;
|
||||
}
|
||||
|
||||
const DownmixCoefficients& SinkContext::GetDownmixCoefficients() const {
|
||||
return downmix_coefficients;
|
||||
}
|
||||
|
||||
} // namespace AudioCore
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
using DownmixCoefficients = std::array<float_le, 4>;
|
||||
|
||||
enum class SinkTypes : u8 {
|
||||
Invalid = 0,
|
||||
Device = 1,
|
||||
@@ -40,7 +42,7 @@ public:
|
||||
bool in_use;
|
||||
INSERT_UNION_PADDING_BYTES(5);
|
||||
};
|
||||
static_assert(sizeof(SinkInfo::CircularBufferIn) == 0x28,
|
||||
static_assert(sizeof(CircularBufferIn) == 0x28,
|
||||
"SinkInfo::CircularBufferIn is in invalid size");
|
||||
|
||||
struct DeviceIn {
|
||||
@@ -50,9 +52,9 @@ public:
|
||||
std::array<u8, AudioCommon::MAX_CHANNEL_COUNT> input;
|
||||
INSERT_UNION_PADDING_BYTES(1);
|
||||
bool down_matrix_enabled;
|
||||
std::array<float_le, 4> down_matrix_coef;
|
||||
DownmixCoefficients down_matrix_coef;
|
||||
};
|
||||
static_assert(sizeof(SinkInfo::DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size");
|
||||
static_assert(sizeof(DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size");
|
||||
|
||||
struct InParams {
|
||||
SinkTypes type{};
|
||||
@@ -62,28 +64,33 @@ public:
|
||||
INSERT_PADDING_WORDS(6);
|
||||
union {
|
||||
// std::array<u8, 0x120> raw{};
|
||||
SinkInfo::DeviceIn device;
|
||||
SinkInfo::CircularBufferIn circular_buffer;
|
||||
DeviceIn device;
|
||||
CircularBufferIn circular_buffer;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(SinkInfo::InParams) == 0x140, "SinkInfo::InParams are an invalid size!");
|
||||
static_assert(sizeof(InParams) == 0x140, "SinkInfo::InParams are an invalid size!");
|
||||
};
|
||||
|
||||
class SinkContext {
|
||||
public:
|
||||
explicit SinkContext(std::size_t sink_count);
|
||||
explicit SinkContext(std::size_t sink_count_);
|
||||
~SinkContext();
|
||||
|
||||
std::size_t GetCount() const;
|
||||
[[nodiscard]] std::size_t GetCount() const;
|
||||
|
||||
void UpdateMainSink(SinkInfo::InParams& in);
|
||||
bool InUse() const;
|
||||
std::vector<u8> OutputBuffers() const;
|
||||
void UpdateMainSink(const SinkInfo::InParams& in);
|
||||
[[nodiscard]] bool InUse() const;
|
||||
[[nodiscard]] std::vector<u8> OutputBuffers() const;
|
||||
|
||||
[[nodiscard]] bool HasDownMixingCoefficients() const;
|
||||
[[nodiscard]] const DownmixCoefficients& GetDownmixCoefficients() const;
|
||||
|
||||
private:
|
||||
bool in_use{false};
|
||||
s32 use_count{};
|
||||
std::array<u8, AudioCommon::MAX_CHANNEL_COUNT> buffers{};
|
||||
std::size_t sink_count{};
|
||||
bool has_downmix_coefs{false};
|
||||
DownmixCoefficients downmix_coefficients{};
|
||||
};
|
||||
} // namespace AudioCore
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id) : id(id) {}
|
||||
ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id_) : id{id_} {}
|
||||
ServerSplitterDestinationData::~ServerSplitterDestinationData() = default;
|
||||
|
||||
void ServerSplitterDestinationData::Update(SplitterInfo::InDestinationParams& header) {
|
||||
@@ -87,7 +87,7 @@ void ServerSplitterDestinationData::UpdateInternalState() {
|
||||
needs_update = false;
|
||||
}
|
||||
|
||||
ServerSplitterInfo::ServerSplitterInfo(s32 id) : id(id) {}
|
||||
ServerSplitterInfo::ServerSplitterInfo(s32 id_) : id(id_) {}
|
||||
ServerSplitterInfo::~ServerSplitterInfo() = default;
|
||||
|
||||
void ServerSplitterInfo::InitializeInfos() {
|
||||
@@ -121,7 +121,7 @@ const ServerSplitterDestinationData* ServerSplitterInfo::GetHead() const {
|
||||
}
|
||||
|
||||
ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) {
|
||||
auto current_head = head;
|
||||
auto* current_head = head;
|
||||
for (std::size_t i = 0; i < depth; i++) {
|
||||
if (current_head == nullptr) {
|
||||
return nullptr;
|
||||
@@ -132,7 +132,7 @@ ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) {
|
||||
}
|
||||
|
||||
const ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) const {
|
||||
auto current_head = head;
|
||||
auto* current_head = head;
|
||||
for (std::size_t i = 0; i < depth; i++) {
|
||||
if (current_head == nullptr) {
|
||||
return nullptr;
|
||||
@@ -245,7 +245,7 @@ ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t i
|
||||
const ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t info,
|
||||
std::size_t data) const {
|
||||
ASSERT(info < info_count);
|
||||
auto& cur_info = GetInfo(info);
|
||||
const auto& cur_info = GetInfo(info);
|
||||
return cur_info.GetData(data);
|
||||
}
|
||||
|
||||
@@ -267,11 +267,11 @@ std::size_t SplitterContext::GetDataCount() const {
|
||||
return data_count;
|
||||
}
|
||||
|
||||
void SplitterContext::Setup(std::size_t _info_count, std::size_t _data_count,
|
||||
void SplitterContext::Setup(std::size_t info_count_, std::size_t data_count_,
|
||||
bool is_splitter_bug_fixed) {
|
||||
|
||||
info_count = _info_count;
|
||||
data_count = _data_count;
|
||||
info_count = info_count_;
|
||||
data_count = data_count_;
|
||||
|
||||
for (std::size_t i = 0; i < info_count; i++) {
|
||||
auto& splitter = infos.emplace_back(static_cast<s32>(i));
|
||||
@@ -364,7 +364,7 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info,
|
||||
// Clear our current destinations
|
||||
auto* current_head = info.GetHead();
|
||||
while (current_head != nullptr) {
|
||||
auto next_head = current_head->GetNextDestination();
|
||||
auto* next_head = current_head->GetNextDestination();
|
||||
current_head->SetNextDestination(nullptr);
|
||||
current_head = next_head;
|
||||
}
|
||||
@@ -471,8 +471,8 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto node_count = edge_matrix.GetNodeCount();
|
||||
for (s32 j = 0; j < static_cast<s32>(node_count); j++) {
|
||||
const auto edge_node_count = edge_matrix.GetNodeCount();
|
||||
for (s32 j = 0; j < static_cast<s32>(edge_node_count); j++) {
|
||||
// Check if our node is connected to our edge matrix
|
||||
if (!edge_matrix.Connected(current_stack_index, j)) {
|
||||
continue;
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
NodeStates();
|
||||
~NodeStates();
|
||||
|
||||
void Initialize(std::size_t _node_count);
|
||||
void Initialize(std::size_t node_count_);
|
||||
bool Tsort(EdgeMatrix& edge_matrix);
|
||||
std::size_t GetIndexPos() const;
|
||||
const std::vector<s32>& GetIndexList() const;
|
||||
@@ -72,15 +72,15 @@ private:
|
||||
void PushTsortResult(s32 index);
|
||||
bool DepthFirstSearch(EdgeMatrix& edge_matrix);
|
||||
void ResetState();
|
||||
void UpdateState(NodeStates::State state, std::size_t i);
|
||||
NodeStates::State GetState(std::size_t i);
|
||||
void UpdateState(State state, std::size_t i);
|
||||
State GetState(std::size_t i);
|
||||
|
||||
std::size_t node_count{};
|
||||
std::vector<bool> was_node_found{};
|
||||
std::vector<bool> was_node_completed{};
|
||||
std::size_t index_pos{};
|
||||
std::vector<s32> index_list{};
|
||||
NodeStates::Stack index_stack{};
|
||||
Stack index_stack{};
|
||||
};
|
||||
|
||||
enum class SplitterMagic : u32_le {
|
||||
@@ -97,8 +97,7 @@ public:
|
||||
s32_le data_count{};
|
||||
INSERT_PADDING_WORDS(5);
|
||||
};
|
||||
static_assert(sizeof(SplitterInfo::InHeader) == 0x20,
|
||||
"SplitterInfo::InHeader is an invalid size");
|
||||
static_assert(sizeof(InHeader) == 0x20, "SplitterInfo::InHeader is an invalid size");
|
||||
|
||||
struct InInfoPrams {
|
||||
SplitterMagic magic{};
|
||||
@@ -107,8 +106,7 @@ public:
|
||||
s32_le length{};
|
||||
s32_le resource_id_base{};
|
||||
};
|
||||
static_assert(sizeof(SplitterInfo::InInfoPrams) == 0x14,
|
||||
"SplitterInfo::InInfoPrams is an invalid size");
|
||||
static_assert(sizeof(InInfoPrams) == 0x14, "SplitterInfo::InInfoPrams is an invalid size");
|
||||
|
||||
struct InDestinationParams {
|
||||
SplitterMagic magic{};
|
||||
@@ -118,13 +116,13 @@ public:
|
||||
bool in_use{};
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(SplitterInfo::InDestinationParams) == 0x70,
|
||||
static_assert(sizeof(InDestinationParams) == 0x70,
|
||||
"SplitterInfo::InDestinationParams is an invalid size");
|
||||
};
|
||||
|
||||
class ServerSplitterDestinationData {
|
||||
public:
|
||||
explicit ServerSplitterDestinationData(s32 id);
|
||||
explicit ServerSplitterDestinationData(s32 id_);
|
||||
~ServerSplitterDestinationData();
|
||||
|
||||
void Update(SplitterInfo::InDestinationParams& header);
|
||||
@@ -153,7 +151,7 @@ private:
|
||||
|
||||
class ServerSplitterInfo {
|
||||
public:
|
||||
explicit ServerSplitterInfo(s32 id);
|
||||
explicit ServerSplitterInfo(s32 id_);
|
||||
~ServerSplitterInfo();
|
||||
|
||||
void InitializeInfos();
|
||||
|
||||
@@ -31,10 +31,10 @@ u32 Stream::GetNumChannels() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format,
|
||||
ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_)
|
||||
: sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
|
||||
sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} {
|
||||
Stream::Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_,
|
||||
ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_)
|
||||
: sample_rate{sample_rate_}, format{format_}, release_callback{std::move(release_callback_)},
|
||||
sink_stream{sink_stream_}, core_timing{core_timing_}, name{std::move(name_)} {
|
||||
release_event =
|
||||
Core::Timing::CreateEvent(name, [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
|
||||
ReleaseActiveBuffer(ns_late);
|
||||
@@ -122,7 +122,7 @@ bool Stream::QueueBuffer(BufferPtr&& buffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Stream::ContainsBuffer(Buffer::Tag tag) const {
|
||||
bool Stream::ContainsBuffer([[maybe_unused]] Buffer::Tag tag) const {
|
||||
UNIMPLEMENTED();
|
||||
return {};
|
||||
}
|
||||
@@ -136,4 +136,14 @@ std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(std::size_t max_count)
|
||||
return tags;
|
||||
}
|
||||
|
||||
std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers() {
|
||||
std::vector<Buffer::Tag> tags;
|
||||
tags.reserve(released_buffers.size());
|
||||
while (!released_buffers.empty()) {
|
||||
tags.push_back(released_buffers.front()->GetTag());
|
||||
released_buffers.pop();
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
} // namespace AudioCore
|
||||
|
||||
@@ -44,8 +44,8 @@ public:
|
||||
/// Callback function type, used to change guest state on a buffer being released
|
||||
using ReleaseCallback = std::function<void()>;
|
||||
|
||||
Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format,
|
||||
ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_);
|
||||
Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_,
|
||||
ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_);
|
||||
|
||||
/// Plays the audio stream
|
||||
void Play();
|
||||
@@ -57,37 +57,40 @@ public:
|
||||
bool QueueBuffer(BufferPtr&& buffer);
|
||||
|
||||
/// Returns true if the audio stream contains a buffer with the specified tag
|
||||
bool ContainsBuffer(Buffer::Tag tag) const;
|
||||
[[nodiscard]] bool ContainsBuffer(Buffer::Tag tag) const;
|
||||
|
||||
/// Returns a vector of recently released buffers specified by tag
|
||||
std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count);
|
||||
[[nodiscard]] std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count);
|
||||
|
||||
/// Returns a vector of all recently released buffers specified by tag
|
||||
[[nodiscard]] std::vector<Buffer::Tag> GetTagsAndReleaseBuffers();
|
||||
|
||||
void SetVolume(float volume);
|
||||
|
||||
float GetVolume() const {
|
||||
[[nodiscard]] float GetVolume() const {
|
||||
return game_volume;
|
||||
}
|
||||
|
||||
/// Returns true if the stream is currently playing
|
||||
bool IsPlaying() const {
|
||||
[[nodiscard]] bool IsPlaying() const {
|
||||
return state == State::Playing;
|
||||
}
|
||||
|
||||
/// Returns the number of queued buffers
|
||||
std::size_t GetQueueSize() const {
|
||||
[[nodiscard]] std::size_t GetQueueSize() const {
|
||||
return queued_buffers.size();
|
||||
}
|
||||
|
||||
/// Gets the sample rate
|
||||
u32 GetSampleRate() const {
|
||||
[[nodiscard]] u32 GetSampleRate() const {
|
||||
return sample_rate;
|
||||
}
|
||||
|
||||
/// Gets the number of channels
|
||||
u32 GetNumChannels() const;
|
||||
[[nodiscard]] u32 GetNumChannels() const;
|
||||
|
||||
/// Get the state
|
||||
State GetState() const;
|
||||
[[nodiscard]] State GetState() const;
|
||||
|
||||
private:
|
||||
/// Plays the next queued buffer in the audio stream, starting playback if necessary
|
||||
@@ -97,7 +100,7 @@ private:
|
||||
void ReleaseActiveBuffer(std::chrono::nanoseconds ns_late = {});
|
||||
|
||||
/// Gets the number of core cycles when the specified buffer will be released
|
||||
std::chrono::nanoseconds GetBufferReleaseNS(const Buffer& buffer) const;
|
||||
[[nodiscard]] std::chrono::nanoseconds GetBufferReleaseNS(const Buffer& buffer) const;
|
||||
|
||||
u32 sample_rate; ///< Sample rate of the stream
|
||||
Format format; ///< Format of the stream
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id) : id(id) {}
|
||||
ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id_) : id(id_) {}
|
||||
ServerVoiceChannelResource::~ServerVoiceChannelResource() = default;
|
||||
|
||||
bool ServerVoiceChannelResource::InUse() const {
|
||||
@@ -209,7 +209,8 @@ void ServerVoiceInfo::UpdateWaveBuffers(
|
||||
|
||||
void ServerVoiceInfo::UpdateWaveBuffer(ServerWaveBuffer& out_wavebuffer,
|
||||
const WaveBuffer& in_wave_buffer, SampleFormat sample_format,
|
||||
bool is_buffer_valid, BehaviorInfo& behavior_info) {
|
||||
bool is_buffer_valid,
|
||||
[[maybe_unused]] BehaviorInfo& behavior_info) {
|
||||
if (!is_buffer_valid && out_wavebuffer.sent_to_dsp) {
|
||||
out_wavebuffer.buffer_address = 0;
|
||||
out_wavebuffer.buffer_size = 0;
|
||||
@@ -400,7 +401,7 @@ bool ServerVoiceInfo::HasValidWaveBuffer(const VoiceState* state) const {
|
||||
return std::find(valid_wb.begin(), valid_wb.end(), true) != valid_wb.end();
|
||||
}
|
||||
|
||||
VoiceContext::VoiceContext(std::size_t voice_count) : voice_count(voice_count) {
|
||||
VoiceContext::VoiceContext(std::size_t voice_count_) : voice_count{voice_count_} {
|
||||
for (std::size_t i = 0; i < voice_count; i++) {
|
||||
voice_channel_resources.emplace_back(static_cast<s32>(i));
|
||||
sorted_voice_info.push_back(&voice_info.emplace_back());
|
||||
|
||||
@@ -118,12 +118,12 @@ public:
|
||||
bool in_use{};
|
||||
INSERT_PADDING_BYTES(11);
|
||||
};
|
||||
static_assert(sizeof(VoiceChannelResource::InParams) == 0x70, "InParams is an invalid size");
|
||||
static_assert(sizeof(InParams) == 0x70, "InParams is an invalid size");
|
||||
};
|
||||
|
||||
class ServerVoiceChannelResource {
|
||||
public:
|
||||
explicit ServerVoiceChannelResource(s32 id);
|
||||
explicit ServerVoiceChannelResource(s32 id_);
|
||||
~ServerVoiceChannelResource();
|
||||
|
||||
bool InUse() const;
|
||||
@@ -174,7 +174,7 @@ public:
|
||||
BehaviorFlags behavior_flags{};
|
||||
INSERT_PADDING_BYTES(16);
|
||||
};
|
||||
static_assert(sizeof(VoiceInfo::InParams) == 0x170, "InParams is an invalid size");
|
||||
static_assert(sizeof(InParams) == 0x170, "InParams is an invalid size");
|
||||
|
||||
struct OutParams {
|
||||
u64_le played_sample_count{};
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
u8 voice_dropped{};
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(VoiceInfo::OutParams) == 0x10, "OutParams is an invalid size");
|
||||
static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size");
|
||||
};
|
||||
|
||||
class ServerVoiceInfo {
|
||||
@@ -263,7 +263,7 @@ private:
|
||||
|
||||
class VoiceContext {
|
||||
public:
|
||||
VoiceContext(std::size_t voice_count);
|
||||
explicit VoiceContext(std::size_t voice_count_);
|
||||
~VoiceContext();
|
||||
|
||||
std::size_t GetVoiceCount() const;
|
||||
|
||||
@@ -102,6 +102,7 @@ add_library(common STATIC
|
||||
atomic_ops.h
|
||||
detached_tasks.cpp
|
||||
detached_tasks.h
|
||||
bit_cast.h
|
||||
bit_field.h
|
||||
bit_util.h
|
||||
cityhash.cpp
|
||||
@@ -111,6 +112,7 @@ add_library(common STATIC
|
||||
common_paths.h
|
||||
common_types.h
|
||||
concepts.h
|
||||
div_ceil.h
|
||||
dynamic_library.cpp
|
||||
dynamic_library.h
|
||||
fiber.cpp
|
||||
|
||||
22
src/common/bit_cast.h
Normal file
22
src/common/bit_cast.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright 2020 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Common {
|
||||
|
||||
template <typename To, typename From>
|
||||
[[nodiscard]] std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> &&
|
||||
std::is_trivially_copyable_v<To>,
|
||||
To>
|
||||
BitCast(const From& src) noexcept {
|
||||
To dst;
|
||||
std::memcpy(&dst, &src, sizeof(To));
|
||||
return dst;
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
26
src/common/div_ceil.h
Normal file
26
src/common/div_ceil.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2020 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Common {
|
||||
|
||||
/// Ceiled integer division.
|
||||
template <typename N, typename D>
|
||||
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeil(
|
||||
N number, D divisor) {
|
||||
return (static_cast<D>(number) + divisor - 1) / divisor;
|
||||
}
|
||||
|
||||
/// Ceiled integer division with logarithmic divisor in base 2
|
||||
template <typename N, typename D>
|
||||
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeilLog2(
|
||||
N value, D alignment_log2) {
|
||||
return (static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2;
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "common/logging/text_formatter.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/threadsafe_queue.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Log {
|
||||
|
||||
@@ -152,10 +153,19 @@ FileBackend::FileBackend(const std::string& filename)
|
||||
void FileBackend::Write(const Entry& entry) {
|
||||
// prevent logs from going over the maximum size (in case its spamming and the user doesn't
|
||||
// know)
|
||||
constexpr std::size_t MAX_BYTES_WRITTEN = 50 * 1024L * 1024L;
|
||||
if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) {
|
||||
constexpr std::size_t MAX_BYTES_WRITTEN = 100 * 1024 * 1024;
|
||||
constexpr std::size_t MAX_BYTES_WRITTEN_EXTENDED = 1024 * 1024 * 1024;
|
||||
|
||||
if (!file.IsOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings::values.extended_logging && bytes_written > MAX_BYTES_WRITTEN_EXTENDED) {
|
||||
return;
|
||||
} else if (!Settings::values.extended_logging && bytes_written > MAX_BYTES_WRITTEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
bytes_written += file.WriteString(FormatLogMessage(entry).append(1, '\n'));
|
||||
if (entry.log_level >= Level::Error) {
|
||||
file.Flush();
|
||||
@@ -222,6 +232,7 @@ void DebuggerBackend::Write(const Entry& entry) {
|
||||
SUB(Service, NPNS) \
|
||||
SUB(Service, NS) \
|
||||
SUB(Service, NVDRV) \
|
||||
SUB(Service, OLSC) \
|
||||
SUB(Service, PCIE) \
|
||||
SUB(Service, PCTL) \
|
||||
SUB(Service, PCV) \
|
||||
|
||||
@@ -95,6 +95,7 @@ enum class Class : ClassType {
|
||||
Service_NPNS, ///< The NPNS service
|
||||
Service_NS, ///< The NS services
|
||||
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
|
||||
Service_OLSC, ///< The OLSC service
|
||||
Service_PCIE, ///< The PCIe service
|
||||
Service_PCTL, ///< The PCTL (Parental control) service
|
||||
Service_PCV, ///< The PCV service
|
||||
|
||||
@@ -43,9 +43,14 @@ public:
|
||||
}
|
||||
|
||||
void resize(std::size_t count) {
|
||||
const auto new_size = count * sizeof(T);
|
||||
if (new_size == alloc_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
FreeMemoryPages(base_ptr, alloc_size);
|
||||
|
||||
alloc_size = count * sizeof(T);
|
||||
alloc_size = new_size;
|
||||
base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ using base_time_point = std::chrono::time_point<base_timer>;
|
||||
|
||||
class StandardWallClock final : public WallClock {
|
||||
public:
|
||||
StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency)
|
||||
: WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) {
|
||||
explicit StandardWallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_)
|
||||
: WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, false) {
|
||||
start_time = base_timer::now();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
WallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, bool is_native)
|
||||
: emulated_cpu_frequency{emulated_cpu_frequency},
|
||||
emulated_clock_frequency{emulated_clock_frequency}, is_native{is_native} {}
|
||||
explicit WallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_, bool is_native_)
|
||||
: emulated_cpu_frequency{emulated_cpu_frequency_},
|
||||
emulated_clock_frequency{emulated_clock_frequency_}, is_native{is_native_} {}
|
||||
|
||||
u64 emulated_cpu_frequency;
|
||||
u64 emulated_clock_frequency;
|
||||
|
||||
@@ -43,10 +43,10 @@ u64 EstimateRDTSCFrequency() {
|
||||
}
|
||||
|
||||
namespace X64 {
|
||||
NativeClock::NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency,
|
||||
u64 rtsc_frequency)
|
||||
: WallClock(emulated_cpu_frequency, emulated_clock_frequency, true), rtsc_frequency{
|
||||
rtsc_frequency} {
|
||||
NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_,
|
||||
u64 rtsc_frequency_)
|
||||
: WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{
|
||||
rtsc_frequency_} {
|
||||
_mm_mfence();
|
||||
last_measure = __rdtsc();
|
||||
accumulated_ticks = 0U;
|
||||
|
||||
@@ -14,7 +14,8 @@ namespace Common {
|
||||
namespace X64 {
|
||||
class NativeClock final : public WallClock {
|
||||
public:
|
||||
NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency);
|
||||
explicit NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_,
|
||||
u64 rtsc_frequency_);
|
||||
|
||||
std::chrono::nanoseconds GetTimeNS() override;
|
||||
|
||||
|
||||
@@ -135,8 +135,6 @@ add_library(core STATIC
|
||||
frontend/framebuffer_layout.cpp
|
||||
frontend/framebuffer_layout.h
|
||||
frontend/input.h
|
||||
gdbstub/gdbstub.cpp
|
||||
gdbstub/gdbstub.h
|
||||
hardware_interrupt_manager.cpp
|
||||
hardware_interrupt_manager.h
|
||||
hle/ipc.h
|
||||
@@ -458,6 +456,8 @@ add_library(core STATIC
|
||||
hle/service/nvflinger/buffer_queue.h
|
||||
hle/service/nvflinger/nvflinger.cpp
|
||||
hle/service/nvflinger/nvflinger.h
|
||||
hle/service/olsc/olsc.cpp
|
||||
hle/service/olsc/olsc.h
|
||||
hle/service/pcie/pcie.cpp
|
||||
hle/service/pcie/pcie.h
|
||||
hle/service/pctl/module.cpp
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hardware_properties.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/kernel/scheduler.h"
|
||||
@@ -96,16 +95,6 @@ public:
|
||||
case Dynarmic::A64::Exception::Yield:
|
||||
return;
|
||||
case Dynarmic::A64::Exception::Breakpoint:
|
||||
if (GDBStub::IsServerEnabled()) {
|
||||
parent.jit->HaltExecution();
|
||||
parent.SetPC(pc);
|
||||
Kernel::Thread* const thread = parent.system.CurrentScheduler().GetCurrentThread();
|
||||
parent.SaveContext(thread->GetContext64());
|
||||
GDBStub::Break();
|
||||
GDBStub::SendTrap(thread, 5);
|
||||
return;
|
||||
}
|
||||
[[fallthrough]];
|
||||
default:
|
||||
ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})",
|
||||
static_cast<std::size_t>(exception), pc, MemoryReadCode(pc));
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "core/file_sys/sdmc_factory.h"
|
||||
#include "core/file_sys/vfs_concat.h"
|
||||
#include "core/file_sys/vfs_real.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hardware_interrupt_manager.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
@@ -92,33 +91,43 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
||||
std::string dir_name;
|
||||
std::string filename;
|
||||
Common::SplitPath(path, &dir_name, &filename, nullptr);
|
||||
|
||||
if (filename == "00") {
|
||||
const auto dir = vfs->OpenDirectory(dir_name, FileSys::Mode::Read);
|
||||
std::vector<FileSys::VirtualFile> concat;
|
||||
for (u8 i = 0; i < 0x10; ++i) {
|
||||
auto next = dir->GetFile(fmt::format("{:02X}", i));
|
||||
if (next != nullptr)
|
||||
|
||||
for (u32 i = 0; i < 0x10; ++i) {
|
||||
const auto file_name = fmt::format("{:02X}", i);
|
||||
auto next = dir->GetFile(file_name);
|
||||
|
||||
if (next != nullptr) {
|
||||
concat.push_back(std::move(next));
|
||||
else {
|
||||
next = dir->GetFile(fmt::format("{:02x}", i));
|
||||
if (next != nullptr)
|
||||
concat.push_back(std::move(next));
|
||||
else
|
||||
} else {
|
||||
next = dir->GetFile(file_name);
|
||||
|
||||
if (next == nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
concat.push_back(std::move(next));
|
||||
}
|
||||
}
|
||||
|
||||
if (concat.empty())
|
||||
if (concat.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(concat, dir->GetName());
|
||||
return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(std::move(concat),
|
||||
dir->GetName());
|
||||
}
|
||||
|
||||
if (Common::FS::IsDirectory(path))
|
||||
return vfs->OpenFile(path + "/" + "main", FileSys::Mode::Read);
|
||||
if (Common::FS::IsDirectory(path)) {
|
||||
return vfs->OpenFile(path + "/main", FileSys::Mode::Read);
|
||||
}
|
||||
|
||||
return vfs->OpenFile(path, FileSys::Mode::Read);
|
||||
}
|
||||
|
||||
struct System::Impl {
|
||||
explicit Impl(System& system)
|
||||
: kernel{system}, fs_controller{system}, memory{system},
|
||||
@@ -145,7 +154,7 @@ struct System::Impl {
|
||||
}
|
||||
|
||||
ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
|
||||
LOG_DEBUG(HW_Memory, "initialized OK");
|
||||
LOG_DEBUG(Core, "initialized OK");
|
||||
|
||||
device_memory = std::make_unique<Core::DeviceMemory>();
|
||||
|
||||
@@ -186,11 +195,8 @@ struct System::Impl {
|
||||
}
|
||||
|
||||
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
|
||||
|
||||
Service::Init(service_manager, system);
|
||||
GDBStub::DeferStart();
|
||||
|
||||
interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system);
|
||||
services = std::make_unique<Service::Services>(service_manager, system);
|
||||
interrupt_manager = std::make_unique<Hardware::InterruptManager>(system);
|
||||
|
||||
// Initialize time manager, which must happen after kernel is created
|
||||
time_manager.Initialize();
|
||||
@@ -208,9 +214,11 @@ struct System::Impl {
|
||||
return ResultStatus::Success;
|
||||
}
|
||||
|
||||
ResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
|
||||
const std::string& filepath) {
|
||||
app_loader = Loader::GetLoader(GetGameFileFromPath(virtual_filesystem, filepath));
|
||||
ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath,
|
||||
std::size_t program_index) {
|
||||
app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
|
||||
program_index);
|
||||
|
||||
if (!app_loader) {
|
||||
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
||||
return ResultStatus::ErrorGetLoader;
|
||||
@@ -224,7 +232,7 @@ struct System::Impl {
|
||||
return init_result;
|
||||
}
|
||||
|
||||
telemetry_session->AddInitialInfo(*app_loader);
|
||||
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
||||
auto main_process =
|
||||
Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland);
|
||||
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
||||
@@ -295,8 +303,7 @@ struct System::Impl {
|
||||
}
|
||||
|
||||
// Shutdown emulation session
|
||||
GDBStub::Shutdown();
|
||||
Service::Shutdown();
|
||||
services.reset();
|
||||
service_manager.reset();
|
||||
cheat_engine.reset();
|
||||
telemetry_session.reset();
|
||||
@@ -306,8 +313,8 @@ struct System::Impl {
|
||||
cpu_manager.Shutdown();
|
||||
|
||||
// Shutdown kernel and core timing
|
||||
kernel.Shutdown();
|
||||
core_timing.Shutdown();
|
||||
kernel.Shutdown();
|
||||
|
||||
// Close app loader
|
||||
app_loader.reset();
|
||||
@@ -338,7 +345,7 @@ struct System::Impl {
|
||||
Service::Glue::ApplicationLaunchProperty launch{};
|
||||
launch.title_id = process.GetTitleID();
|
||||
|
||||
FileSys::PatchManager pm{launch.title_id};
|
||||
FileSys::PatchManager pm{launch.title_id, fs_controller, *content_provider};
|
||||
launch.version = pm.GetGameVersion().value_or(0);
|
||||
|
||||
// TODO(DarkLordZach): When FSController/Game Card Support is added, if
|
||||
@@ -398,6 +405,9 @@ struct System::Impl {
|
||||
/// Service manager
|
||||
std::shared_ptr<Service::SM::ServiceManager> service_manager;
|
||||
|
||||
/// Services
|
||||
std::unique_ptr<Service::Services> services;
|
||||
|
||||
/// Telemetry session for this emulation session
|
||||
std::unique_ptr<Core::TelemetrySession> telemetry_session;
|
||||
|
||||
@@ -413,6 +423,8 @@ struct System::Impl {
|
||||
bool is_multicore{};
|
||||
bool is_async_gpu{};
|
||||
|
||||
ExecuteProgramCallback execute_program_callback;
|
||||
|
||||
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
|
||||
std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_dynarmic{};
|
||||
};
|
||||
@@ -444,8 +456,13 @@ void System::InvalidateCpuInstructionCaches() {
|
||||
impl->kernel.InvalidateAllInstructionCaches();
|
||||
}
|
||||
|
||||
System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath) {
|
||||
return impl->Load(*this, emu_window, filepath);
|
||||
void System::Shutdown() {
|
||||
impl->Shutdown();
|
||||
}
|
||||
|
||||
System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
|
||||
std::size_t program_index) {
|
||||
return impl->Load(*this, emu_window, filepath, program_index);
|
||||
}
|
||||
|
||||
bool System::IsPoweredOn() const {
|
||||
@@ -632,7 +649,11 @@ const std::string& System::GetStatusDetails() const {
|
||||
return impl->status_details;
|
||||
}
|
||||
|
||||
Loader::AppLoader& System::GetAppLoader() const {
|
||||
Loader::AppLoader& System::GetAppLoader() {
|
||||
return *impl->app_loader;
|
||||
}
|
||||
|
||||
const Loader::AppLoader& System::GetAppLoader() const {
|
||||
return *impl->app_loader;
|
||||
}
|
||||
|
||||
@@ -748,14 +769,6 @@ const System::CurrentBuildProcessID& System::GetCurrentProcessBuildID() const {
|
||||
return impl->build_id;
|
||||
}
|
||||
|
||||
System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) {
|
||||
return impl->Init(*this, emu_window);
|
||||
}
|
||||
|
||||
void System::Shutdown() {
|
||||
impl->Shutdown();
|
||||
}
|
||||
|
||||
Service::SM::ServiceManager& System::ServiceManager() {
|
||||
return *impl->service_manager;
|
||||
}
|
||||
@@ -786,4 +799,16 @@ bool System::IsMulticore() const {
|
||||
return impl->is_multicore;
|
||||
}
|
||||
|
||||
void System::RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback) {
|
||||
impl->execute_program_callback = std::move(callback);
|
||||
}
|
||||
|
||||
void System::ExecuteProgram(std::size_t program_index) {
|
||||
if (impl->execute_program_callback) {
|
||||
impl->execute_program_callback(program_index);
|
||||
} else {
|
||||
LOG_CRITICAL(Core, "execute_program_callback must be initialized by the frontend");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
||||
179
src/core/core.h
179
src/core/core.h
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -144,19 +145,19 @@ public:
|
||||
* Run the OS and Application
|
||||
* This function will start emulation and run the relevant devices
|
||||
*/
|
||||
ResultStatus Run();
|
||||
[[nodiscard]] ResultStatus Run();
|
||||
|
||||
/**
|
||||
* Pause the OS and Application
|
||||
* This function will pause emulation and stop the relevant devices
|
||||
*/
|
||||
ResultStatus Pause();
|
||||
[[nodiscard]] ResultStatus Pause();
|
||||
|
||||
/**
|
||||
* Step the CPU one instruction
|
||||
* @return Result status, indicating whether or not the operation succeeded.
|
||||
*/
|
||||
ResultStatus SingleStep();
|
||||
[[nodiscard]] ResultStatus SingleStep();
|
||||
|
||||
/**
|
||||
* Invalidate the CPU instruction caches
|
||||
@@ -173,22 +174,24 @@ public:
|
||||
* @param emu_window Reference to the host-system window used for video output and keyboard
|
||||
* input.
|
||||
* @param filepath String path to the executable application to load on the host file system.
|
||||
* @param program_index Specifies the index within the container of the program to launch.
|
||||
* @returns ResultStatus code, indicating if the operation succeeded.
|
||||
*/
|
||||
ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath);
|
||||
[[nodiscard]] ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
|
||||
std::size_t program_index = 0);
|
||||
|
||||
/**
|
||||
* Indicates if the emulated system is powered on (all subsystems initialized and able to run an
|
||||
* application).
|
||||
* @returns True if the emulated system is powered on, otherwise false.
|
||||
*/
|
||||
bool IsPoweredOn() const;
|
||||
[[nodiscard]] bool IsPoweredOn() const;
|
||||
|
||||
/// Gets a reference to the telemetry session for this emulation session.
|
||||
Core::TelemetrySession& TelemetrySession();
|
||||
[[nodiscard]] Core::TelemetrySession& TelemetrySession();
|
||||
|
||||
/// Gets a reference to the telemetry session for this emulation session.
|
||||
const Core::TelemetrySession& TelemetrySession() const;
|
||||
[[nodiscard]] const Core::TelemetrySession& TelemetrySession() const;
|
||||
|
||||
/// Prepare the core emulation for a reschedule
|
||||
void PrepareReschedule();
|
||||
@@ -197,185 +200,178 @@ public:
|
||||
void PrepareReschedule(u32 core_index);
|
||||
|
||||
/// Gets and resets core performance statistics
|
||||
PerfStatsResults GetAndResetPerfStats();
|
||||
[[nodiscard]] PerfStatsResults GetAndResetPerfStats();
|
||||
|
||||
/// Gets an ARM interface to the CPU core that is currently running
|
||||
ARM_Interface& CurrentArmInterface();
|
||||
[[nodiscard]] ARM_Interface& CurrentArmInterface();
|
||||
|
||||
/// Gets an ARM interface to the CPU core that is currently running
|
||||
const ARM_Interface& CurrentArmInterface() const;
|
||||
[[nodiscard]] const ARM_Interface& CurrentArmInterface() const;
|
||||
|
||||
/// Gets the index of the currently running CPU core
|
||||
std::size_t CurrentCoreIndex() const;
|
||||
[[nodiscard]] std::size_t CurrentCoreIndex() const;
|
||||
|
||||
/// Gets the scheduler for the CPU core that is currently running
|
||||
Kernel::Scheduler& CurrentScheduler();
|
||||
[[nodiscard]] Kernel::Scheduler& CurrentScheduler();
|
||||
|
||||
/// Gets the scheduler for the CPU core that is currently running
|
||||
const Kernel::Scheduler& CurrentScheduler() const;
|
||||
[[nodiscard]] const Kernel::Scheduler& CurrentScheduler() const;
|
||||
|
||||
/// Gets the physical core for the CPU core that is currently running
|
||||
Kernel::PhysicalCore& CurrentPhysicalCore();
|
||||
[[nodiscard]] Kernel::PhysicalCore& CurrentPhysicalCore();
|
||||
|
||||
/// Gets the physical core for the CPU core that is currently running
|
||||
const Kernel::PhysicalCore& CurrentPhysicalCore() const;
|
||||
[[nodiscard]] const Kernel::PhysicalCore& CurrentPhysicalCore() const;
|
||||
|
||||
/// Gets a reference to an ARM interface for the CPU core with the specified index
|
||||
ARM_Interface& ArmInterface(std::size_t core_index);
|
||||
[[nodiscard]] ARM_Interface& ArmInterface(std::size_t core_index);
|
||||
|
||||
/// Gets a const reference to an ARM interface from the CPU core with the specified index
|
||||
const ARM_Interface& ArmInterface(std::size_t core_index) const;
|
||||
[[nodiscard]] const ARM_Interface& ArmInterface(std::size_t core_index) const;
|
||||
|
||||
CpuManager& GetCpuManager();
|
||||
/// Gets a reference to the underlying CPU manager.
|
||||
[[nodiscard]] CpuManager& GetCpuManager();
|
||||
|
||||
const CpuManager& GetCpuManager() const;
|
||||
/// Gets a const reference to the underlying CPU manager
|
||||
[[nodiscard]] const CpuManager& GetCpuManager() const;
|
||||
|
||||
/// Gets a reference to the exclusive monitor
|
||||
ExclusiveMonitor& Monitor();
|
||||
[[nodiscard]] ExclusiveMonitor& Monitor();
|
||||
|
||||
/// Gets a constant reference to the exclusive monitor
|
||||
const ExclusiveMonitor& Monitor() const;
|
||||
[[nodiscard]] const ExclusiveMonitor& Monitor() const;
|
||||
|
||||
/// Gets a mutable reference to the system memory instance.
|
||||
Core::Memory::Memory& Memory();
|
||||
[[nodiscard]] Core::Memory::Memory& Memory();
|
||||
|
||||
/// Gets a constant reference to the system memory instance.
|
||||
const Core::Memory::Memory& Memory() const;
|
||||
[[nodiscard]] const Core::Memory::Memory& Memory() const;
|
||||
|
||||
/// Gets a mutable reference to the GPU interface
|
||||
Tegra::GPU& GPU();
|
||||
[[nodiscard]] Tegra::GPU& GPU();
|
||||
|
||||
/// Gets an immutable reference to the GPU interface.
|
||||
const Tegra::GPU& GPU() const;
|
||||
[[nodiscard]] const Tegra::GPU& GPU() const;
|
||||
|
||||
/// Gets a mutable reference to the renderer.
|
||||
VideoCore::RendererBase& Renderer();
|
||||
[[nodiscard]] VideoCore::RendererBase& Renderer();
|
||||
|
||||
/// Gets an immutable reference to the renderer.
|
||||
const VideoCore::RendererBase& Renderer() const;
|
||||
[[nodiscard]] const VideoCore::RendererBase& Renderer() const;
|
||||
|
||||
/// Gets the scheduler for the CPU core with the specified index
|
||||
Kernel::Scheduler& Scheduler(std::size_t core_index);
|
||||
[[nodiscard]] Kernel::Scheduler& Scheduler(std::size_t core_index);
|
||||
|
||||
/// Gets the scheduler for the CPU core with the specified index
|
||||
const Kernel::Scheduler& Scheduler(std::size_t core_index) const;
|
||||
[[nodiscard]] const Kernel::Scheduler& Scheduler(std::size_t core_index) const;
|
||||
|
||||
/// Gets the global scheduler
|
||||
Kernel::GlobalScheduler& GlobalScheduler();
|
||||
[[nodiscard]] Kernel::GlobalScheduler& GlobalScheduler();
|
||||
|
||||
/// Gets the global scheduler
|
||||
const Kernel::GlobalScheduler& GlobalScheduler() const;
|
||||
[[nodiscard]] const Kernel::GlobalScheduler& GlobalScheduler() const;
|
||||
|
||||
/// Gets the manager for the guest device memory
|
||||
Core::DeviceMemory& DeviceMemory();
|
||||
[[nodiscard]] Core::DeviceMemory& DeviceMemory();
|
||||
|
||||
/// Gets the manager for the guest device memory
|
||||
const Core::DeviceMemory& DeviceMemory() const;
|
||||
[[nodiscard]] const Core::DeviceMemory& DeviceMemory() const;
|
||||
|
||||
/// Provides a pointer to the current process
|
||||
Kernel::Process* CurrentProcess();
|
||||
[[nodiscard]] Kernel::Process* CurrentProcess();
|
||||
|
||||
/// Provides a constant pointer to the current process.
|
||||
const Kernel::Process* CurrentProcess() const;
|
||||
[[nodiscard]] const Kernel::Process* CurrentProcess() const;
|
||||
|
||||
/// Provides a reference to the core timing instance.
|
||||
Timing::CoreTiming& CoreTiming();
|
||||
[[nodiscard]] Timing::CoreTiming& CoreTiming();
|
||||
|
||||
/// Provides a constant reference to the core timing instance.
|
||||
const Timing::CoreTiming& CoreTiming() const;
|
||||
[[nodiscard]] const Timing::CoreTiming& CoreTiming() const;
|
||||
|
||||
/// Provides a reference to the interrupt manager instance.
|
||||
Core::Hardware::InterruptManager& InterruptManager();
|
||||
[[nodiscard]] Core::Hardware::InterruptManager& InterruptManager();
|
||||
|
||||
/// Provides a constant reference to the interrupt manager instance.
|
||||
const Core::Hardware::InterruptManager& InterruptManager() const;
|
||||
[[nodiscard]] const Core::Hardware::InterruptManager& InterruptManager() const;
|
||||
|
||||
/// Provides a reference to the kernel instance.
|
||||
Kernel::KernelCore& Kernel();
|
||||
[[nodiscard]] Kernel::KernelCore& Kernel();
|
||||
|
||||
/// Provides a constant reference to the kernel instance.
|
||||
const Kernel::KernelCore& Kernel() const;
|
||||
[[nodiscard]] const Kernel::KernelCore& Kernel() const;
|
||||
|
||||
/// Provides a reference to the internal PerfStats instance.
|
||||
Core::PerfStats& GetPerfStats();
|
||||
[[nodiscard]] Core::PerfStats& GetPerfStats();
|
||||
|
||||
/// Provides a constant reference to the internal PerfStats instance.
|
||||
const Core::PerfStats& GetPerfStats() const;
|
||||
[[nodiscard]] const Core::PerfStats& GetPerfStats() const;
|
||||
|
||||
/// Provides a reference to the frame limiter;
|
||||
Core::FrameLimiter& FrameLimiter();
|
||||
[[nodiscard]] Core::FrameLimiter& FrameLimiter();
|
||||
|
||||
/// Provides a constant referent to the frame limiter
|
||||
const Core::FrameLimiter& FrameLimiter() const;
|
||||
[[nodiscard]] const Core::FrameLimiter& FrameLimiter() const;
|
||||
|
||||
/// Gets the name of the current game
|
||||
Loader::ResultStatus GetGameName(std::string& out) const;
|
||||
[[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const;
|
||||
|
||||
void SetStatus(ResultStatus new_status, const char* details);
|
||||
|
||||
const std::string& GetStatusDetails() const;
|
||||
[[nodiscard]] const std::string& GetStatusDetails() const;
|
||||
|
||||
Loader::AppLoader& GetAppLoader() const;
|
||||
[[nodiscard]] Loader::AppLoader& GetAppLoader();
|
||||
[[nodiscard]] const Loader::AppLoader& GetAppLoader() const;
|
||||
|
||||
Service::SM::ServiceManager& ServiceManager();
|
||||
const Service::SM::ServiceManager& ServiceManager() const;
|
||||
[[nodiscard]] Service::SM::ServiceManager& ServiceManager();
|
||||
[[nodiscard]] const Service::SM::ServiceManager& ServiceManager() const;
|
||||
|
||||
void SetFilesystem(FileSys::VirtualFilesystem vfs);
|
||||
|
||||
FileSys::VirtualFilesystem GetFilesystem() const;
|
||||
[[nodiscard]] FileSys::VirtualFilesystem GetFilesystem() const;
|
||||
|
||||
void RegisterCheatList(const std::vector<Memory::CheatEntry>& list,
|
||||
const std::array<u8, 0x20>& build_id, VAddr main_region_begin,
|
||||
u64 main_region_size);
|
||||
|
||||
void SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set);
|
||||
|
||||
void SetDefaultAppletFrontendSet();
|
||||
|
||||
Service::AM::Applets::AppletManager& GetAppletManager();
|
||||
|
||||
const Service::AM::Applets::AppletManager& GetAppletManager() const;
|
||||
[[nodiscard]] Service::AM::Applets::AppletManager& GetAppletManager();
|
||||
[[nodiscard]] const Service::AM::Applets::AppletManager& GetAppletManager() const;
|
||||
|
||||
void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider);
|
||||
|
||||
FileSys::ContentProvider& GetContentProvider();
|
||||
[[nodiscard]] FileSys::ContentProvider& GetContentProvider();
|
||||
[[nodiscard]] const FileSys::ContentProvider& GetContentProvider() const;
|
||||
|
||||
const FileSys::ContentProvider& GetContentProvider() const;
|
||||
|
||||
Service::FileSystem::FileSystemController& GetFileSystemController();
|
||||
|
||||
const Service::FileSystem::FileSystemController& GetFileSystemController() const;
|
||||
[[nodiscard]] Service::FileSystem::FileSystemController& GetFileSystemController();
|
||||
[[nodiscard]] const Service::FileSystem::FileSystemController& GetFileSystemController() const;
|
||||
|
||||
void RegisterContentProvider(FileSys::ContentProviderUnionSlot slot,
|
||||
FileSys::ContentProvider* provider);
|
||||
|
||||
void ClearContentProvider(FileSys::ContentProviderUnionSlot slot);
|
||||
|
||||
const Reporter& GetReporter() const;
|
||||
[[nodiscard]] const Reporter& GetReporter() const;
|
||||
|
||||
Service::Glue::ARPManager& GetARPManager();
|
||||
[[nodiscard]] Service::Glue::ARPManager& GetARPManager();
|
||||
[[nodiscard]] const Service::Glue::ARPManager& GetARPManager() const;
|
||||
|
||||
const Service::Glue::ARPManager& GetARPManager() const;
|
||||
[[nodiscard]] Service::APM::Controller& GetAPMController();
|
||||
[[nodiscard]] const Service::APM::Controller& GetAPMController() const;
|
||||
|
||||
Service::APM::Controller& GetAPMController();
|
||||
[[nodiscard]] Service::LM::Manager& GetLogManager();
|
||||
[[nodiscard]] const Service::LM::Manager& GetLogManager() const;
|
||||
|
||||
const Service::APM::Controller& GetAPMController() const;
|
||||
|
||||
Service::LM::Manager& GetLogManager();
|
||||
|
||||
const Service::LM::Manager& GetLogManager() const;
|
||||
|
||||
Service::Time::TimeManager& GetTimeManager();
|
||||
|
||||
const Service::Time::TimeManager& GetTimeManager() const;
|
||||
[[nodiscard]] Service::Time::TimeManager& GetTimeManager();
|
||||
[[nodiscard]] const Service::Time::TimeManager& GetTimeManager() const;
|
||||
|
||||
void SetExitLock(bool locked);
|
||||
|
||||
bool GetExitLock() const;
|
||||
[[nodiscard]] bool GetExitLock() const;
|
||||
|
||||
void SetCurrentProcessBuildID(const CurrentBuildProcessID& id);
|
||||
|
||||
const CurrentBuildProcessID& GetCurrentProcessBuildID() const;
|
||||
[[nodiscard]] const CurrentBuildProcessID& GetCurrentProcessBuildID() const;
|
||||
|
||||
/// Register a host thread as an emulated CPU Core.
|
||||
void RegisterCoreThread(std::size_t id);
|
||||
@@ -390,19 +386,28 @@ public:
|
||||
void ExitDynarmicProfile();
|
||||
|
||||
/// Tells if system is running on multicore.
|
||||
bool IsMulticore() const;
|
||||
[[nodiscard]] bool IsMulticore() const;
|
||||
|
||||
/// Type used for the frontend to designate a callback for System to re-launch the application
|
||||
/// using a specified program index.
|
||||
using ExecuteProgramCallback = std::function<void(std::size_t)>;
|
||||
|
||||
/**
|
||||
* Registers a callback from the frontend for System to re-launch the application using a
|
||||
* specified program index.
|
||||
* @param callback Callback from the frontend to relaunch the application.
|
||||
*/
|
||||
void RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback);
|
||||
|
||||
/**
|
||||
* Instructs the frontend to re-launch the application using the specified program_index.
|
||||
* @param program_index Specifies the index within the application of the program to launch.
|
||||
*/
|
||||
void ExecuteProgram(std::size_t program_index);
|
||||
|
||||
private:
|
||||
System();
|
||||
|
||||
/**
|
||||
* Initialize the emulated system.
|
||||
* @param emu_window Reference to the host-system window used for video output and keyboard
|
||||
* input.
|
||||
* @return ResultStatus code, indicating if the operation succeeded.
|
||||
*/
|
||||
ResultStatus Init(Frontend::EmuWindow& emu_window);
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ using TimedCallback =
|
||||
|
||||
/// Contains the characteristics of a particular event.
|
||||
struct EventType {
|
||||
EventType(TimedCallback&& callback, std::string&& name)
|
||||
: callback{std::move(callback)}, name{std::move(name)} {}
|
||||
explicit EventType(TimedCallback&& callback_, std::string&& name_)
|
||||
: callback{std::move(callback_)}, name{std::move(name_)} {}
|
||||
|
||||
/// The event's callback function.
|
||||
TimedCallback callback;
|
||||
@@ -67,8 +67,8 @@ public:
|
||||
void Shutdown();
|
||||
|
||||
/// Sets if emulation is multicore or single core, must be set before Initialize
|
||||
void SetMulticore(bool is_multicore) {
|
||||
this->is_multicore = is_multicore;
|
||||
void SetMulticore(bool is_multicore_) {
|
||||
is_multicore = is_multicore_;
|
||||
}
|
||||
|
||||
/// Check if it's using host timing.
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#include "common/fiber.h"
|
||||
#include "common/microprofile.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/thread.h"
|
||||
#include "core/arm/exclusive_monitor.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/cpu_manager.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/physical_core.h"
|
||||
#include "core/hle/kernel/scheduler.h"
|
||||
@@ -343,6 +343,16 @@ void CpuManager::RunThread(std::size_t core) {
|
||||
data.initialized = true;
|
||||
const bool sc_sync = !is_async_gpu && !is_multicore;
|
||||
bool sc_sync_first_use = sc_sync;
|
||||
|
||||
// Cleanup
|
||||
SCOPE_EXIT({
|
||||
data.host_context->Exit();
|
||||
data.enter_barrier.reset();
|
||||
data.exit_barrier.reset();
|
||||
data.initialized = false;
|
||||
MicroProfileOnThreadExit();
|
||||
});
|
||||
|
||||
/// Running
|
||||
while (running_mode) {
|
||||
data.is_running = false;
|
||||
@@ -351,6 +361,12 @@ void CpuManager::RunThread(std::size_t core) {
|
||||
system.GPU().ObtainContext();
|
||||
sc_sync_first_use = false;
|
||||
}
|
||||
|
||||
// Abort if emulation was killed before the session really starts
|
||||
if (!system.IsPoweredOn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& scheduler = system.Kernel().CurrentScheduler();
|
||||
Kernel::Thread* current_thread = scheduler.GetCurrentThread();
|
||||
data.is_running = true;
|
||||
@@ -360,13 +376,6 @@ void CpuManager::RunThread(std::size_t core) {
|
||||
data.exit_barrier->Wait();
|
||||
data.is_paused = false;
|
||||
}
|
||||
/// Time to cleanup
|
||||
data.host_context->Exit();
|
||||
data.enter_barrier.reset();
|
||||
data.exit_barrier.reset();
|
||||
data.initialized = false;
|
||||
|
||||
MicroProfileOnThreadExit();
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
||||
@@ -29,7 +29,7 @@ constexpr std::array partition_names{
|
||||
"logo",
|
||||
};
|
||||
|
||||
XCI::XCI(VirtualFile file_)
|
||||
XCI::XCI(VirtualFile file_, std::size_t program_index)
|
||||
: file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA},
|
||||
partitions(partition_names.size()),
|
||||
partitions_raw(partition_names.size()), keys{Core::Crypto::KeyManager::Instance()} {
|
||||
@@ -62,7 +62,8 @@ XCI::XCI(VirtualFile file_)
|
||||
}
|
||||
|
||||
secure_partition = std::make_shared<NSP>(
|
||||
main_hfs.GetFile(partition_names[static_cast<std::size_t>(XCIPartition::Secure)]));
|
||||
main_hfs.GetFile(partition_names[static_cast<std::size_t>(XCIPartition::Secure)]),
|
||||
program_index);
|
||||
|
||||
ncas = secure_partition->GetNCAsCollapsed();
|
||||
program =
|
||||
|
||||
@@ -78,7 +78,7 @@ enum class XCIPartition : u8 { Update, Normal, Secure, Logo };
|
||||
|
||||
class XCI : public ReadOnlyVfsDirectory {
|
||||
public:
|
||||
explicit XCI(VirtualFile file);
|
||||
explicit XCI(VirtualFile file, std::size_t program_index = 0);
|
||||
~XCI() override;
|
||||
|
||||
Loader::ResultStatus GetStatus() const;
|
||||
|
||||
@@ -112,7 +112,10 @@ bool IsDirValidAndNonEmpty(const VirtualDir& dir) {
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
PatchManager::PatchManager(u64 title_id) : title_id(title_id) {}
|
||||
PatchManager::PatchManager(u64 title_id_,
|
||||
const Service::FileSystem::FileSystemController& fs_controller_,
|
||||
const ContentProvider& content_provider_)
|
||||
: title_id{title_id_}, fs_controller{fs_controller_}, content_provider{content_provider_} {}
|
||||
|
||||
PatchManager::~PatchManager() = default;
|
||||
|
||||
@@ -128,34 +131,30 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
|
||||
|
||||
if (Settings::values.dump_exefs) {
|
||||
LOG_INFO(Loader, "Dumping ExeFS for title_id={:016X}", title_id);
|
||||
const auto dump_dir =
|
||||
Core::System::GetInstance().GetFileSystemController().GetModificationDumpRoot(title_id);
|
||||
const auto dump_dir = fs_controller.GetModificationDumpRoot(title_id);
|
||||
if (dump_dir != nullptr) {
|
||||
const auto exefs_dir = GetOrCreateDirectoryRelative(dump_dir, "/exefs");
|
||||
VfsRawCopyD(exefs, exefs_dir);
|
||||
}
|
||||
}
|
||||
|
||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
||||
|
||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||
const auto update_disabled =
|
||||
std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend();
|
||||
|
||||
// Game Updates
|
||||
const auto update_tid = GetUpdateTitleID(title_id);
|
||||
const auto update = installed.GetEntry(update_tid, ContentRecordType::Program);
|
||||
const auto update = content_provider.GetEntry(update_tid, ContentRecordType::Program);
|
||||
|
||||
if (!update_disabled && update != nullptr && update->GetExeFS() != nullptr &&
|
||||
update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) {
|
||||
LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully",
|
||||
FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0)));
|
||||
FormatTitleVersion(content_provider.GetEntryVersion(update_tid).value_or(0)));
|
||||
exefs = update->GetExeFS();
|
||||
}
|
||||
|
||||
// LayeredExeFS
|
||||
const auto load_dir =
|
||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
if (load_dir != nullptr && load_dir->GetSize() > 0) {
|
||||
auto patch_dirs = load_dir->GetSubdirectories();
|
||||
std::sort(
|
||||
@@ -241,8 +240,7 @@ std::vector<u8> PatchManager::PatchNSO(const std::vector<u8>& nso, const std::st
|
||||
if (Settings::values.dump_nso) {
|
||||
LOG_INFO(Loader, "Dumping NSO for name={}, build_id={}, title_id={:016X}", name, build_id,
|
||||
title_id);
|
||||
const auto dump_dir =
|
||||
Core::System::GetInstance().GetFileSystemController().GetModificationDumpRoot(title_id);
|
||||
const auto dump_dir = fs_controller.GetModificationDumpRoot(title_id);
|
||||
if (dump_dir != nullptr) {
|
||||
const auto nso_dir = GetOrCreateDirectoryRelative(dump_dir, "/nso");
|
||||
const auto file = nso_dir->CreateFile(fmt::format("{}-{}.nso", name, build_id));
|
||||
@@ -254,8 +252,7 @@ std::vector<u8> PatchManager::PatchNSO(const std::vector<u8>& nso, const std::st
|
||||
|
||||
LOG_INFO(Loader, "Patching NSO for name={}, build_id={}", name, build_id);
|
||||
|
||||
const auto load_dir =
|
||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
if (load_dir == nullptr) {
|
||||
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
||||
return nso;
|
||||
@@ -298,8 +295,7 @@ bool PatchManager::HasNSOPatch(const BuildID& build_id_) const {
|
||||
|
||||
LOG_INFO(Loader, "Querying NSO patch existence for build_id={}", build_id);
|
||||
|
||||
const auto load_dir =
|
||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
if (load_dir == nullptr) {
|
||||
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
||||
return false;
|
||||
@@ -313,8 +309,8 @@ bool PatchManager::HasNSOPatch(const BuildID& build_id_) const {
|
||||
}
|
||||
|
||||
std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList(
|
||||
const Core::System& system, const BuildID& build_id_) const {
|
||||
const auto load_dir = system.GetFileSystemController().GetModificationLoadRoot(title_id);
|
||||
const BuildID& build_id_) const {
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
if (load_dir == nullptr) {
|
||||
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
||||
return {};
|
||||
@@ -347,9 +343,9 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList(
|
||||
return out;
|
||||
}
|
||||
|
||||
static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) {
|
||||
const auto load_dir =
|
||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
||||
static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type,
|
||||
const Service::FileSystem::FileSystemController& fs_controller) {
|
||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
if ((type != ContentRecordType::Program && type != ContentRecordType::Data) ||
|
||||
load_dir == nullptr || load_dir->GetSize() <= 0) {
|
||||
return;
|
||||
@@ -411,19 +407,19 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content
|
||||
const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}",
|
||||
title_id, static_cast<u8>(type));
|
||||
|
||||
if (type == ContentRecordType::Program || type == ContentRecordType::Data)
|
||||
if (type == ContentRecordType::Program || type == ContentRecordType::Data) {
|
||||
LOG_INFO(Loader, "{}", log_string);
|
||||
else
|
||||
} else {
|
||||
LOG_DEBUG(Loader, "{}", log_string);
|
||||
}
|
||||
|
||||
if (romfs == nullptr)
|
||||
if (romfs == nullptr) {
|
||||
return romfs;
|
||||
|
||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
||||
}
|
||||
|
||||
// Game Updates
|
||||
const auto update_tid = GetUpdateTitleID(title_id);
|
||||
const auto update = installed.GetEntryRaw(update_tid, type);
|
||||
const auto update = content_provider.GetEntryRaw(update_tid, type);
|
||||
|
||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||
const auto update_disabled =
|
||||
@@ -434,7 +430,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content
|
||||
if (new_nca->GetStatus() == Loader::ResultStatus::Success &&
|
||||
new_nca->GetRomFS() != nullptr) {
|
||||
LOG_INFO(Loader, " RomFS: Update ({}) applied successfully",
|
||||
FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0)));
|
||||
FormatTitleVersion(content_provider.GetEntryVersion(update_tid).value_or(0)));
|
||||
romfs = new_nca->GetRomFS();
|
||||
}
|
||||
} else if (!update_disabled && update_raw != nullptr) {
|
||||
@@ -447,7 +443,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content
|
||||
}
|
||||
|
||||
// LayeredFS
|
||||
ApplyLayeredFS(romfs, title_id, type);
|
||||
ApplyLayeredFS(romfs, title_id, type, fs_controller);
|
||||
|
||||
return romfs;
|
||||
}
|
||||
@@ -458,12 +454,11 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||
}
|
||||
|
||||
std::map<std::string, std::string, std::less<>> out;
|
||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||
|
||||
// Game Updates
|
||||
const auto update_tid = GetUpdateTitleID(title_id);
|
||||
PatchManager update{update_tid};
|
||||
PatchManager update{update_tid, fs_controller, content_provider};
|
||||
const auto metadata = update.GetControlMetadata();
|
||||
const auto& nacp = metadata.first;
|
||||
|
||||
@@ -474,8 +469,8 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||
if (nacp != nullptr) {
|
||||
out.insert_or_assign(update_label, nacp->GetVersionString());
|
||||
} else {
|
||||
if (installed.HasEntry(update_tid, ContentRecordType::Program)) {
|
||||
const auto meta_ver = installed.GetEntryVersion(update_tid);
|
||||
if (content_provider.HasEntry(update_tid, ContentRecordType::Program)) {
|
||||
const auto meta_ver = content_provider.GetEntryVersion(update_tid);
|
||||
if (meta_ver.value_or(0) == 0) {
|
||||
out.insert_or_assign(update_label, "");
|
||||
} else {
|
||||
@@ -487,8 +482,7 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||
}
|
||||
|
||||
// General Mods (LayeredFS and IPS)
|
||||
const auto mod_dir =
|
||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
||||
const auto mod_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||
if (mod_dir != nullptr && mod_dir->GetSize() > 0) {
|
||||
for (const auto& mod : mod_dir->GetSubdirectories()) {
|
||||
std::string types;
|
||||
@@ -532,13 +526,15 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||
}
|
||||
|
||||
// DLC
|
||||
const auto dlc_entries = installed.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data);
|
||||
const auto dlc_entries =
|
||||
content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data);
|
||||
std::vector<ContentProviderEntry> dlc_match;
|
||||
dlc_match.reserve(dlc_entries.size());
|
||||
std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
|
||||
[this, &installed](const ContentProviderEntry& entry) {
|
||||
[this](const ContentProviderEntry& entry) {
|
||||
return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == title_id &&
|
||||
installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success;
|
||||
content_provider.GetEntry(entry)->GetStatus() ==
|
||||
Loader::ResultStatus::Success;
|
||||
});
|
||||
if (!dlc_match.empty()) {
|
||||
// Ensure sorted so DLC IDs show in order.
|
||||
@@ -559,19 +555,16 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||
}
|
||||
|
||||
std::optional<u32> PatchManager::GetGameVersion() const {
|
||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
||||
const auto update_tid = GetUpdateTitleID(title_id);
|
||||
if (installed.HasEntry(update_tid, ContentRecordType::Program)) {
|
||||
return installed.GetEntryVersion(update_tid);
|
||||
if (content_provider.HasEntry(update_tid, ContentRecordType::Program)) {
|
||||
return content_provider.GetEntryVersion(update_tid);
|
||||
}
|
||||
|
||||
return installed.GetEntryVersion(title_id);
|
||||
return content_provider.GetEntryVersion(title_id);
|
||||
}
|
||||
|
||||
PatchManager::Metadata PatchManager::GetControlMetadata() const {
|
||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
||||
|
||||
const auto base_control_nca = installed.GetEntry(title_id, ContentRecordType::Control);
|
||||
const auto base_control_nca = content_provider.GetEntry(title_id, ContentRecordType::Control);
|
||||
if (base_control_nca == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -17,8 +17,13 @@ namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::FileSystem {
|
||||
class FileSystemController;
|
||||
}
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
class ContentProvider;
|
||||
class NCA;
|
||||
class NACP;
|
||||
|
||||
@@ -29,7 +34,9 @@ public:
|
||||
using Metadata = std::pair<std::unique_ptr<NACP>, VirtualFile>;
|
||||
using PatchVersionNames = std::map<std::string, std::string, std::less<>>;
|
||||
|
||||
explicit PatchManager(u64 title_id);
|
||||
explicit PatchManager(u64 title_id_,
|
||||
const Service::FileSystem::FileSystemController& fs_controller_,
|
||||
const ContentProvider& content_provider_);
|
||||
~PatchManager();
|
||||
|
||||
[[nodiscard]] u64 GetTitleID() const;
|
||||
@@ -50,7 +57,7 @@ public:
|
||||
|
||||
// Creates a CheatList object with all
|
||||
[[nodiscard]] std::vector<Core::Memory::CheatEntry> CreateCheatList(
|
||||
const Core::System& system, const BuildID& build_id) const;
|
||||
const BuildID& build_id) const;
|
||||
|
||||
// Currently tracked RomFS patches:
|
||||
// - Game Updates
|
||||
@@ -80,6 +87,8 @@ private:
|
||||
const std::string& build_id) const;
|
||||
|
||||
u64 title_id;
|
||||
const Service::FileSystem::FileSystemController& fs_controller;
|
||||
const ContentProvider& content_provider;
|
||||
};
|
||||
|
||||
} // namespace FileSys
|
||||
|
||||
@@ -37,10 +37,12 @@ void RomFSFactory::SetPackedUpdate(VirtualFile update_raw) {
|
||||
}
|
||||
|
||||
ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess(u64 current_process_title_id) const {
|
||||
if (!updatable)
|
||||
if (!updatable) {
|
||||
return MakeResult<VirtualFile>(file);
|
||||
}
|
||||
|
||||
const PatchManager patch_manager(current_process_title_id);
|
||||
const PatchManager patch_manager{current_process_title_id, filesystem_controller,
|
||||
content_provider};
|
||||
return MakeResult<VirtualFile>(
|
||||
patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw));
|
||||
}
|
||||
|
||||
@@ -70,7 +70,8 @@ std::string SaveDataAttribute::DebugInfo() const {
|
||||
static_cast<u8>(rank), index);
|
||||
}
|
||||
|
||||
SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save_directory)) {
|
||||
SaveDataFactory::SaveDataFactory(Core::System& system_, VirtualDir save_directory_)
|
||||
: dir{std::move(save_directory_)}, system{system_} {
|
||||
// Delete all temporary storages
|
||||
// On hardware, it is expected that temporary storage be empty at first use.
|
||||
dir->DeleteSubdirectoryRecursive("temp");
|
||||
@@ -83,7 +84,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space,
|
||||
PrintSaveDataAttributeWarnings(meta);
|
||||
|
||||
const auto save_directory =
|
||||
GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id);
|
||||
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
|
||||
|
||||
auto out = dir->CreateDirectoryRelative(save_directory);
|
||||
|
||||
@@ -100,7 +101,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
|
||||
const SaveDataAttribute& meta) const {
|
||||
|
||||
const auto save_directory =
|
||||
GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id);
|
||||
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
|
||||
|
||||
auto out = dir->GetDirectoryRelative(save_directory);
|
||||
|
||||
@@ -135,13 +136,14 @@ std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id,
|
||||
u128 user_id, u64 save_id) {
|
||||
std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId space,
|
||||
SaveDataType type, u64 title_id, u128 user_id,
|
||||
u64 save_id) {
|
||||
// According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
|
||||
// be interpreted as the title id of the current process.
|
||||
if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
|
||||
if (title_id == 0) {
|
||||
title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
|
||||
title_id = system.CurrentProcess()->GetTitleID();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +169,7 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ
|
||||
|
||||
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
||||
u128 user_id) const {
|
||||
const auto path = GetFullPath(SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
|
||||
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
|
||||
const auto dir = GetOrCreateDirectoryRelative(this->dir, path);
|
||||
|
||||
const auto size_file = dir->GetFile(SAVE_DATA_SIZE_FILENAME);
|
||||
@@ -182,7 +184,7 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
||||
|
||||
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
|
||||
SaveDataSize new_value) const {
|
||||
const auto path = GetFullPath(SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
|
||||
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
|
||||
const auto dir = GetOrCreateDirectoryRelative(this->dir, path);
|
||||
|
||||
const auto size_file = dir->CreateFile(SAVE_DATA_SIZE_FILENAME);
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include "core/file_sys/vfs.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
enum class SaveDataSpaceId : u8 {
|
||||
@@ -84,7 +88,7 @@ struct SaveDataSize {
|
||||
/// File system interface to the SaveData archive
|
||||
class SaveDataFactory {
|
||||
public:
|
||||
explicit SaveDataFactory(VirtualDir dir);
|
||||
explicit SaveDataFactory(Core::System& system_, VirtualDir save_directory_);
|
||||
~SaveDataFactory();
|
||||
|
||||
ResultVal<VirtualDir> Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const;
|
||||
@@ -93,8 +97,8 @@ public:
|
||||
VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const;
|
||||
|
||||
static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);
|
||||
static std::string GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id,
|
||||
u128 user_id, u64 save_id);
|
||||
static std::string GetFullPath(Core::System& system, SaveDataSpaceId space, SaveDataType type,
|
||||
u64 title_id, u128 user_id, u64 save_id);
|
||||
|
||||
SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;
|
||||
void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
|
||||
@@ -102,6 +106,7 @@ public:
|
||||
|
||||
private:
|
||||
VirtualDir dir;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
} // namespace FileSys
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
NSP::NSP(VirtualFile file_)
|
||||
: file(std::move(file_)), status{Loader::ResultStatus::Success},
|
||||
NSP::NSP(VirtualFile file_, std::size_t program_index)
|
||||
: file(std::move(file_)), program_index(program_index), status{Loader::ResultStatus::Success},
|
||||
pfs(std::make_shared<PartitionFilesystem>(file)), keys{Core::Crypto::KeyManager::Instance()} {
|
||||
if (pfs->GetStatus() != Loader::ResultStatus::Success) {
|
||||
status = pfs->GetStatus();
|
||||
@@ -146,7 +146,7 @@ std::shared_ptr<NCA> NSP::GetNCA(u64 title_id, ContentRecordType type, TitleType
|
||||
if (extracted)
|
||||
LOG_WARNING(Service_FS, "called on an NSP that is of type extracted.");
|
||||
|
||||
const auto title_id_iter = ncas.find(title_id);
|
||||
const auto title_id_iter = ncas.find(title_id + program_index);
|
||||
if (title_id_iter == ncas.end())
|
||||
return nullptr;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ enum class ContentRecordType : u8;
|
||||
|
||||
class NSP : public ReadOnlyVfsDirectory {
|
||||
public:
|
||||
explicit NSP(VirtualFile file);
|
||||
explicit NSP(VirtualFile file, std::size_t program_index = 0);
|
||||
~NSP() override;
|
||||
|
||||
Loader::ResultStatus GetStatus() const;
|
||||
@@ -69,6 +69,8 @@ private:
|
||||
|
||||
VirtualFile file;
|
||||
|
||||
const std::size_t program_index;
|
||||
|
||||
bool extracted = false;
|
||||
Loader::ResultStatus status;
|
||||
std::map<u64, Loader::ResultStatus> program_status;
|
||||
|
||||
@@ -102,8 +102,8 @@ public:
|
||||
float render_surface_scale = 1.0f;
|
||||
};
|
||||
|
||||
/// Polls window events
|
||||
virtual void PollEvents() = 0;
|
||||
/// Called from GPU thread when a frame is displayed.
|
||||
virtual void OnFrameDisplayed() {}
|
||||
|
||||
/**
|
||||
* Returns a GraphicsContext that the frontend provides to be used for rendering.
|
||||
|
||||
@@ -30,10 +30,12 @@ public:
|
||||
virtual StatusType GetStatus() const {
|
||||
return {};
|
||||
}
|
||||
virtual bool GetAnalogDirectionStatus(AnalogDirection direction) const {
|
||||
virtual bool GetAnalogDirectionStatus([[maybe_unused]] AnalogDirection direction) const {
|
||||
return {};
|
||||
}
|
||||
virtual bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const {
|
||||
virtual bool SetRumblePlay([[maybe_unused]] f32 amp_low, [[maybe_unused]] f32 freq_low,
|
||||
[[maybe_unused]] f32 amp_high,
|
||||
[[maybe_unused]] f32 freq_high) const {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
@@ -161,10 +163,15 @@ using MotionStatus = std::tuple<Common::Vec3<float>, Common::Vec3<float>, Common
|
||||
using MotionDevice = InputDevice<MotionStatus>;
|
||||
|
||||
/**
|
||||
* A touch device is an input device that returns a tuple of two floats and a bool. The floats are
|
||||
* A touch status is an object that returns a tuple of two floats and a bool. The floats are
|
||||
* x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed.
|
||||
*/
|
||||
using TouchDevice = InputDevice<std::tuple<float, float, bool>>;
|
||||
using TouchStatus = std::tuple<float, float, bool>;
|
||||
|
||||
/**
|
||||
* A touch device is an input device that returns a touch status object
|
||||
*/
|
||||
using TouchDevice = InputDevice<TouchStatus>;
|
||||
|
||||
/**
|
||||
* A mouse device is an input device that returns a tuple of two floats and four ints.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,114 +0,0 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// Originally written by Sven Peter <sven@fail0verflow.com> for anergistic.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
|
||||
namespace GDBStub {
|
||||
|
||||
/// Breakpoint Method
|
||||
enum class BreakpointType {
|
||||
None, ///< None
|
||||
Execute, ///< Execution Breakpoint
|
||||
Read, ///< Read Breakpoint
|
||||
Write, ///< Write Breakpoint
|
||||
Access ///< Access (R/W) Breakpoint
|
||||
};
|
||||
|
||||
struct BreakpointAddress {
|
||||
VAddr address;
|
||||
BreakpointType type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the port the gdbstub should use to listen for connections.
|
||||
*
|
||||
* @param port Port to listen for connection
|
||||
*/
|
||||
void SetServerPort(u16 port);
|
||||
|
||||
/**
|
||||
* Starts or stops the server if possible.
|
||||
*
|
||||
* @param status Set the server to enabled or disabled.
|
||||
*/
|
||||
void ToggleServer(bool status);
|
||||
|
||||
/// Start the gdbstub server.
|
||||
void Init();
|
||||
|
||||
/**
|
||||
* Defer initialization of the gdbstub to the first packet processing functions.
|
||||
* This avoids a case where the gdbstub thread is frozen after initialization
|
||||
* and fails to respond in time to packets.
|
||||
*/
|
||||
void DeferStart();
|
||||
|
||||
/// Stop gdbstub server.
|
||||
void Shutdown();
|
||||
|
||||
/// Checks if the gdbstub server is enabled.
|
||||
bool IsServerEnabled();
|
||||
|
||||
/// Returns true if there is an active socket connection.
|
||||
bool IsConnected();
|
||||
|
||||
/// Register module.
|
||||
void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext = true);
|
||||
|
||||
/**
|
||||
* Signal to the gdbstub server that it should halt CPU execution.
|
||||
*
|
||||
* @param is_memory_break If true, the break resulted from a memory breakpoint.
|
||||
*/
|
||||
void Break(bool is_memory_break = false);
|
||||
|
||||
/// Determine if there was a memory breakpoint.
|
||||
bool IsMemoryBreak();
|
||||
|
||||
/// Read and handle packet from gdb client.
|
||||
void HandlePacket();
|
||||
|
||||
/**
|
||||
* Get the nearest breakpoint of the specified type at the given address.
|
||||
*
|
||||
* @param addr Address to search from.
|
||||
* @param type Type of breakpoint.
|
||||
*/
|
||||
BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, GDBStub::BreakpointType type);
|
||||
|
||||
/**
|
||||
* Check if a breakpoint of the specified type exists at the given address.
|
||||
*
|
||||
* @param addr Address of breakpoint.
|
||||
* @param type Type of breakpoint.
|
||||
*/
|
||||
bool CheckBreakpoint(VAddr addr, GDBStub::BreakpointType type);
|
||||
|
||||
/// If set to true, the CPU will halt at the beginning of the next CPU loop.
|
||||
bool GetCpuHaltFlag();
|
||||
|
||||
/// If set to true and the CPU is halted, the CPU will step one instruction.
|
||||
bool GetCpuStepFlag();
|
||||
|
||||
/**
|
||||
* When set to true, the CPU will step one instruction when the CPU is halted next.
|
||||
*
|
||||
* @param is_step
|
||||
*/
|
||||
void SetCpuStepFlag(bool is_step);
|
||||
|
||||
/**
|
||||
* Send trap signal from thread back to the gdbstub server.
|
||||
*
|
||||
* @param thread Sending thread.
|
||||
* @param trap Trap no.
|
||||
*/
|
||||
void SendTrap(Kernel::Thread* thread, int trap);
|
||||
} // namespace GDBStub
|
||||
@@ -681,7 +681,7 @@ static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) {
|
||||
}
|
||||
|
||||
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
|
||||
static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr address, u64 len) {
|
||||
static void OutputDebugString(Core::System& system, VAddr address, u64 len) {
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ union ResultCode {
|
||||
BitField<0, 9, ErrorModule> module;
|
||||
BitField<9, 13, u32> description;
|
||||
|
||||
constexpr explicit ResultCode(u32 raw) : raw(raw) {}
|
||||
constexpr explicit ResultCode(u32 raw_) : raw(raw_) {}
|
||||
|
||||
constexpr ResultCode(ErrorModule module_, u32 description_)
|
||||
: raw(module.FormatValue(module_) | description.FormatValue(description_)) {}
|
||||
|
||||
@@ -47,8 +47,8 @@ static constexpr u32 SanitizeJPEGSize(std::size_t size) {
|
||||
|
||||
class IManagerForSystemService final : public ServiceFramework<IManagerForSystemService> {
|
||||
public:
|
||||
explicit IManagerForSystemService(Common::UUID user_id)
|
||||
: ServiceFramework("IManagerForSystemService") {
|
||||
explicit IManagerForSystemService(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IManagerForSystemService"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CheckAvailability"},
|
||||
@@ -83,8 +83,8 @@ public:
|
||||
// 3.0.0+
|
||||
class IFloatingRegistrationRequest final : public ServiceFramework<IFloatingRegistrationRequest> {
|
||||
public:
|
||||
explicit IFloatingRegistrationRequest(Common::UUID user_id)
|
||||
: ServiceFramework("IFloatingRegistrationRequest") {
|
||||
explicit IFloatingRegistrationRequest(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IFloatingRegistrationRequest"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetSessionId"},
|
||||
@@ -108,7 +108,8 @@ public:
|
||||
|
||||
class IAdministrator final : public ServiceFramework<IAdministrator> {
|
||||
public:
|
||||
explicit IAdministrator(Common::UUID user_id) : ServiceFramework("IAdministrator") {
|
||||
explicit IAdministrator(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IAdministrator"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CheckAvailability"},
|
||||
@@ -165,8 +166,8 @@ public:
|
||||
|
||||
class IAuthorizationRequest final : public ServiceFramework<IAuthorizationRequest> {
|
||||
public:
|
||||
explicit IAuthorizationRequest(Common::UUID user_id)
|
||||
: ServiceFramework("IAuthorizationRequest") {
|
||||
explicit IAuthorizationRequest(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IAuthorizationRequest"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetSessionId"},
|
||||
@@ -184,7 +185,8 @@ public:
|
||||
|
||||
class IOAuthProcedure final : public ServiceFramework<IOAuthProcedure> {
|
||||
public:
|
||||
explicit IOAuthProcedure(Common::UUID user_id) : ServiceFramework("IOAuthProcedure") {
|
||||
explicit IOAuthProcedure(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IOAuthProcedure"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "PrepareAsync"},
|
||||
@@ -202,8 +204,8 @@ public:
|
||||
// 3.0.0+
|
||||
class IOAuthProcedureForExternalNsa final : public ServiceFramework<IOAuthProcedureForExternalNsa> {
|
||||
public:
|
||||
explicit IOAuthProcedureForExternalNsa(Common::UUID user_id)
|
||||
: ServiceFramework("IOAuthProcedureForExternalNsa") {
|
||||
explicit IOAuthProcedureForExternalNsa(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IOAuthProcedureForExternalNsa"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "PrepareAsync"},
|
||||
@@ -225,8 +227,8 @@ public:
|
||||
class IOAuthProcedureForNintendoAccountLinkage final
|
||||
: public ServiceFramework<IOAuthProcedureForNintendoAccountLinkage> {
|
||||
public:
|
||||
explicit IOAuthProcedureForNintendoAccountLinkage(Common::UUID user_id)
|
||||
: ServiceFramework("IOAuthProcedureForNintendoAccountLinkage") {
|
||||
explicit IOAuthProcedureForNintendoAccountLinkage(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IOAuthProcedureForNintendoAccountLinkage"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "PrepareAsync"},
|
||||
@@ -246,7 +248,8 @@ public:
|
||||
|
||||
class INotifier final : public ServiceFramework<INotifier> {
|
||||
public:
|
||||
explicit INotifier(Common::UUID user_id) : ServiceFramework("INotifier") {
|
||||
explicit INotifier(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "INotifier"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetSystemEvent"},
|
||||
@@ -259,9 +262,9 @@ public:
|
||||
|
||||
class IProfileCommon : public ServiceFramework<IProfileCommon> {
|
||||
public:
|
||||
explicit IProfileCommon(const char* name, bool editor_commands, Common::UUID user_id,
|
||||
ProfileManager& profile_manager)
|
||||
: ServiceFramework(name), profile_manager(profile_manager), user_id(user_id) {
|
||||
explicit IProfileCommon(Core::System& system_, const char* name, bool editor_commands,
|
||||
Common::UUID user_id_, ProfileManager& profile_manager_)
|
||||
: ServiceFramework{system_, name}, profile_manager{profile_manager_}, user_id{user_id_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IProfileCommon::Get, "Get"},
|
||||
{1, &IProfileCommon::GetBase, "GetBase"},
|
||||
@@ -427,19 +430,21 @@ protected:
|
||||
|
||||
class IProfile final : public IProfileCommon {
|
||||
public:
|
||||
IProfile(Common::UUID user_id, ProfileManager& profile_manager)
|
||||
: IProfileCommon("IProfile", false, user_id, profile_manager) {}
|
||||
explicit IProfile(Core::System& system_, Common::UUID user_id_,
|
||||
ProfileManager& profile_manager_)
|
||||
: IProfileCommon{system_, "IProfile", false, user_id_, profile_manager_} {}
|
||||
};
|
||||
|
||||
class IProfileEditor final : public IProfileCommon {
|
||||
public:
|
||||
IProfileEditor(Common::UUID user_id, ProfileManager& profile_manager)
|
||||
: IProfileCommon("IProfileEditor", true, user_id, profile_manager) {}
|
||||
explicit IProfileEditor(Core::System& system_, Common::UUID user_id_,
|
||||
ProfileManager& profile_manager_)
|
||||
: IProfileCommon{system_, "IProfileEditor", true, user_id_, profile_manager_} {}
|
||||
};
|
||||
|
||||
class IAsyncContext final : public ServiceFramework<IAsyncContext> {
|
||||
public:
|
||||
explicit IAsyncContext(Common::UUID user_id) : ServiceFramework("IAsyncContext") {
|
||||
explicit IAsyncContext(Core::System& system_) : ServiceFramework{system_, "IAsyncContext"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetSystemEvent"},
|
||||
@@ -455,7 +460,8 @@ public:
|
||||
|
||||
class ISessionObject final : public ServiceFramework<ISessionObject> {
|
||||
public:
|
||||
explicit ISessionObject(Common::UUID user_id) : ServiceFramework("ISessionObject") {
|
||||
explicit ISessionObject(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "ISessionObject"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{999, nullptr, "Dummy"},
|
||||
@@ -468,7 +474,8 @@ public:
|
||||
|
||||
class IGuestLoginRequest final : public ServiceFramework<IGuestLoginRequest> {
|
||||
public:
|
||||
explicit IGuestLoginRequest(Common::UUID) : ServiceFramework("IGuestLoginRequest") {
|
||||
explicit IGuestLoginRequest(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IGuestLoginRequest"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetSessionId"},
|
||||
@@ -487,8 +494,8 @@ public:
|
||||
|
||||
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
|
||||
public:
|
||||
explicit IManagerForApplication(Common::UUID user_id)
|
||||
: ServiceFramework("IManagerForApplication"), user_id(user_id) {
|
||||
explicit IManagerForApplication(Core::System& system_, Common::UUID user_id_)
|
||||
: ServiceFramework{system_, "IManagerForApplication"}, user_id{user_id_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
|
||||
@@ -534,8 +541,8 @@ private:
|
||||
class IAsyncNetworkServiceLicenseKindContext final
|
||||
: public ServiceFramework<IAsyncNetworkServiceLicenseKindContext> {
|
||||
public:
|
||||
explicit IAsyncNetworkServiceLicenseKindContext(Common::UUID user_id)
|
||||
: ServiceFramework("IAsyncNetworkServiceLicenseKindContext") {
|
||||
explicit IAsyncNetworkServiceLicenseKindContext(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IAsyncNetworkServiceLicenseKindContext"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetSystemEvent"},
|
||||
@@ -554,8 +561,8 @@ public:
|
||||
class IOAuthProcedureForUserRegistration final
|
||||
: public ServiceFramework<IOAuthProcedureForUserRegistration> {
|
||||
public:
|
||||
explicit IOAuthProcedureForUserRegistration(Common::UUID user_id)
|
||||
: ServiceFramework("IOAuthProcedureForUserRegistration") {
|
||||
explicit IOAuthProcedureForUserRegistration(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IOAuthProcedureForUserRegistration"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "PrepareAsync"},
|
||||
@@ -578,7 +585,7 @@ public:
|
||||
|
||||
class DAUTH_O final : public ServiceFramework<DAUTH_O> {
|
||||
public:
|
||||
explicit DAUTH_O(Common::UUID) : ServiceFramework("dauth:o") {
|
||||
explicit DAUTH_O(Core::System& system_, Common::UUID) : ServiceFramework{system_, "dauth:o"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "EnsureAuthenticationTokenCacheAsync"}, // [5.0.0-5.1.0] GeneratePostData
|
||||
@@ -597,7 +604,8 @@ public:
|
||||
// 6.0.0+
|
||||
class IAsyncResult final : public ServiceFramework<IAsyncResult> {
|
||||
public:
|
||||
explicit IAsyncResult(Common::UUID user_id) : ServiceFramework("IAsyncResult") {
|
||||
explicit IAsyncResult(Core::System& system_, Common::UUID)
|
||||
: ServiceFramework{system_, "IAsyncResult"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetResult"},
|
||||
@@ -656,7 +664,7 @@ void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IProfile>(user_id, *profile_manager);
|
||||
rb.PushIpcInterface<IProfile>(system, user_id, *profile_manager);
|
||||
}
|
||||
|
||||
void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx) {
|
||||
@@ -731,7 +739,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IManagerForApplication>(profile_manager->GetLastOpenedUser());
|
||||
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
|
||||
}
|
||||
|
||||
void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
|
||||
@@ -742,8 +750,10 @@ void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx
|
||||
bool is_locked = false;
|
||||
|
||||
if (res != Loader::ResultStatus::Success) {
|
||||
FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
|
||||
auto nacp_unique = pm.GetControlMetadata().first;
|
||||
const FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID(),
|
||||
system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
const auto nacp_unique = pm.GetControlMetadata().first;
|
||||
|
||||
if (nacp_unique != nullptr) {
|
||||
is_locked = nacp_unique->GetUserAccountSwitchLock();
|
||||
@@ -767,7 +777,7 @@ void Module::Interface::GetProfileEditor(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IProfileEditor>(user_id, *profile_manager);
|
||||
rb.PushIpcInterface<IProfileEditor>(system, user_id, *profile_manager);
|
||||
}
|
||||
|
||||
void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
|
||||
@@ -789,7 +799,7 @@ void Module::Interface::LoadOpenContext(Kernel::HLERequestContext& ctx) {
|
||||
// TODO: Find the differences between this and GetBaasAccountManagerForApplication
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IManagerForApplication>(profile_manager->GetLastOpenedUser());
|
||||
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
|
||||
}
|
||||
|
||||
void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) {
|
||||
@@ -825,11 +835,11 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex
|
||||
rb.PushRaw<u128>(profile_manager->GetUser(0)->uuid);
|
||||
}
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module,
|
||||
std::shared_ptr<ProfileManager> profile_manager, Core::System& system,
|
||||
const char* name)
|
||||
: ServiceFramework(name), module(std::move(module)),
|
||||
profile_manager(std::move(profile_manager)), system(system) {}
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module_,
|
||||
std::shared_ptr<ProfileManager> profile_manager_,
|
||||
Core::System& system_, const char* name)
|
||||
: ServiceFramework{system_, name}, module{std::move(module_)}, profile_manager{std::move(
|
||||
profile_manager_)} {}
|
||||
|
||||
Module::Interface::~Interface() = default;
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ class Module final {
|
||||
public:
|
||||
class Interface : public ServiceFramework<Interface> {
|
||||
public:
|
||||
explicit Interface(std::shared_ptr<Module> module,
|
||||
std::shared_ptr<ProfileManager> profile_manager, Core::System& system,
|
||||
explicit Interface(std::shared_ptr<Module> module_,
|
||||
std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_,
|
||||
const char* name);
|
||||
~Interface() override;
|
||||
|
||||
@@ -60,7 +60,6 @@ public:
|
||||
protected:
|
||||
std::shared_ptr<Module> module;
|
||||
std::shared_ptr<ProfileManager> profile_manager;
|
||||
Core::System& system;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ struct LaunchParameterAccountPreselectedUser {
|
||||
static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88);
|
||||
|
||||
IWindowController::IWindowController(Core::System& system_)
|
||||
: ServiceFramework("IWindowController"), system{system_} {
|
||||
: ServiceFramework{system_, "IWindowController"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CreateWindow"},
|
||||
@@ -99,7 +99,8 @@ void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx)
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
IAudioController::IAudioController() : ServiceFramework("IAudioController") {
|
||||
IAudioController::IAudioController(Core::System& system_)
|
||||
: ServiceFramework{system_, "IAudioController"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"},
|
||||
@@ -180,7 +181,8 @@ void IAudioController::SetTransparentAudioRate(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") {
|
||||
IDisplayController::IDisplayController(Core::System& system_)
|
||||
: ServiceFramework{system_, "IDisplayController"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetLastForegroundCaptureImage"},
|
||||
@@ -219,7 +221,8 @@ IDisplayController::IDisplayController() : ServiceFramework("IDisplayController"
|
||||
|
||||
IDisplayController::~IDisplayController() = default;
|
||||
|
||||
IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} {
|
||||
IDebugFunctions::IDebugFunctions(Core::System& system_)
|
||||
: ServiceFramework{system_, "IDebugFunctions"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "NotifyMessageToHomeMenuForDebug"},
|
||||
@@ -246,9 +249,8 @@ IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} {
|
||||
|
||||
IDebugFunctions::~IDebugFunctions() = default;
|
||||
|
||||
ISelfController::ISelfController(Core::System& system,
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
|
||||
: ServiceFramework("ISelfController"), system(system), nvflinger(std::move(nvflinger)) {
|
||||
ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_)
|
||||
: ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISelfController::Exit, "Exit"},
|
||||
@@ -458,8 +460,8 @@ void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx)
|
||||
|
||||
// TODO(Subv): Find out how AM determines the display to use, for now just
|
||||
// create the layer in the Default display.
|
||||
const auto display_id = nvflinger->OpenDisplay("Default");
|
||||
const auto layer_id = nvflinger->CreateLayer(*display_id);
|
||||
const auto display_id = nvflinger.OpenDisplay("Default");
|
||||
const auto layer_id = nvflinger.CreateLayer(*display_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -476,8 +478,8 @@ void ISelfController::CreateManagedDisplaySeparableLayer(Kernel::HLERequestConte
|
||||
// Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse
|
||||
// side effects.
|
||||
// TODO: Support multiple layers
|
||||
const auto display_id = nvflinger->OpenDisplay("Default");
|
||||
const auto layer_id = nvflinger->CreateLayer(*display_id);
|
||||
const auto display_id = nvflinger.OpenDisplay("Default");
|
||||
const auto layer_id = nvflinger.CreateLayer(*display_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -606,9 +608,9 @@ void AppletMessageQueue::RequestExit() {
|
||||
PushMessage(AppletMessage::ExitRequested);
|
||||
}
|
||||
|
||||
ICommonStateGetter::ICommonStateGetter(Core::System& system,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue)
|
||||
: ServiceFramework("ICommonStateGetter"), system(system), msg_queue(std::move(msg_queue)) {
|
||||
ICommonStateGetter::ICommonStateGetter(Core::System& system_,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue_)
|
||||
: ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
|
||||
@@ -796,8 +798,9 @@ private:
|
||||
std::vector<u8> buffer;
|
||||
};
|
||||
|
||||
IStorage::IStorage(std::vector<u8>&& buffer)
|
||||
: ServiceFramework("IStorage"), impl{std::make_shared<StorageDataImpl>(std::move(buffer))} {
|
||||
IStorage::IStorage(Core::System& system_, std::vector<u8>&& buffer)
|
||||
: ServiceFramework{system_, "IStorage"}, impl{std::make_shared<StorageDataImpl>(
|
||||
std::move(buffer))} {
|
||||
Register();
|
||||
}
|
||||
|
||||
@@ -820,7 +823,7 @@ void IStorage::Open(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IStorageAccessor>(*this);
|
||||
rb.PushIpcInterface<IStorageAccessor>(system, *this);
|
||||
}
|
||||
|
||||
void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
|
||||
@@ -842,8 +845,8 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
|
||||
public:
|
||||
explicit ILibraryAppletAccessor(std::shared_ptr<Applets::Applet> applet)
|
||||
: ServiceFramework("ILibraryAppletAccessor"), applet(std::move(applet)) {
|
||||
explicit ILibraryAppletAccessor(Core::System& system_, std::shared_ptr<Applets::Applet> applet_)
|
||||
: ServiceFramework{system_, "ILibraryAppletAccessor"}, applet{std::move(applet_)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"},
|
||||
@@ -998,8 +1001,8 @@ private:
|
||||
std::shared_ptr<Applets::Applet> applet;
|
||||
};
|
||||
|
||||
IStorageAccessor::IStorageAccessor(IStorage& storage)
|
||||
: ServiceFramework("IStorageAccessor"), backing(storage) {
|
||||
IStorageAccessor::IStorageAccessor(Core::System& system_, IStorage& backing_)
|
||||
: ServiceFramework{system_, "IStorageAccessor"}, backing{backing_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IStorageAccessor::GetSize, "GetSize"},
|
||||
@@ -1070,7 +1073,7 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_)
|
||||
: ServiceFramework("ILibraryAppletCreator"), system{system_} {
|
||||
: ServiceFramework{system_, "ILibraryAppletCreator"} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"},
|
||||
{1, nullptr, "TerminateAllLibraryApplets"},
|
||||
@@ -1106,7 +1109,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::ILibraryAppletAccessor>(applet);
|
||||
rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet);
|
||||
}
|
||||
|
||||
void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
|
||||
@@ -1118,7 +1121,7 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::IStorage>(std::move(buffer));
|
||||
rb.PushIpcInterface<IStorage>(system, std::move(buffer));
|
||||
}
|
||||
|
||||
void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) {
|
||||
@@ -1145,11 +1148,11 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IStorage>(std::move(memory));
|
||||
rb.PushIpcInterface<IStorage>(system, std::move(memory));
|
||||
}
|
||||
|
||||
IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
: ServiceFramework("IApplicationFunctions"), system{system_} {
|
||||
: ServiceFramework{system_, "IApplicationFunctions"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
|
||||
@@ -1189,9 +1192,9 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
{102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"},
|
||||
{110, &IApplicationFunctions::QueryApplicationPlayStatistics, "QueryApplicationPlayStatistics"},
|
||||
{111, &IApplicationFunctions::QueryApplicationPlayStatisticsByUid, "QueryApplicationPlayStatisticsByUid"},
|
||||
{120, nullptr, "ExecuteProgram"},
|
||||
{121, nullptr, "ClearUserChannel"},
|
||||
{122, nullptr, "UnpopToUserChannel"},
|
||||
{120, &IApplicationFunctions::ExecuteProgram, "ExecuteProgram"},
|
||||
{121, &IApplicationFunctions::ClearUserChannel, "ClearUserChannel"},
|
||||
{122, &IApplicationFunctions::UnpopToUserChannel, "UnpopToUserChannel"},
|
||||
{123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"},
|
||||
{124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
|
||||
{130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
|
||||
@@ -1301,7 +1304,7 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
|
||||
if (data.has_value()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IStorage>(std::move(*data));
|
||||
rb.PushIpcInterface<IStorage>(system, std::move(*data));
|
||||
launch_popped_application_specific = true;
|
||||
return;
|
||||
}
|
||||
@@ -1324,7 +1327,7 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
|
||||
std::vector<u8> buffer(sizeof(LaunchParameterAccountPreselectedUser));
|
||||
std::memcpy(buffer.data(), ¶ms, buffer.size());
|
||||
|
||||
rb.PushIpcInterface<IStorage>(std::move(buffer));
|
||||
rb.PushIpcInterface<IStorage>(system, std::move(buffer));
|
||||
launch_popped_account_preselect = true;
|
||||
return;
|
||||
}
|
||||
@@ -1381,13 +1384,16 @@ void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
|
||||
const auto res = [this] {
|
||||
const auto title_id = system.CurrentProcess()->GetTitleID();
|
||||
|
||||
FileSys::PatchManager pm{title_id};
|
||||
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
auto res = pm.GetControlMetadata();
|
||||
if (res.first != nullptr) {
|
||||
return res;
|
||||
}
|
||||
|
||||
FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id)};
|
||||
const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id),
|
||||
system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
return pm_update.GetControlMetadata();
|
||||
}();
|
||||
|
||||
@@ -1415,13 +1421,16 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
|
||||
const auto res = [this] {
|
||||
const auto title_id = system.CurrentProcess()->GetTitleID();
|
||||
|
||||
FileSys::PatchManager pm{title_id};
|
||||
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
auto res = pm.GetControlMetadata();
|
||||
if (res.first != nullptr) {
|
||||
return res;
|
||||
}
|
||||
|
||||
FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id)};
|
||||
const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id),
|
||||
system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
return pm_update.GetControlMetadata();
|
||||
}();
|
||||
|
||||
@@ -1556,6 +1565,34 @@ void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLEReque
|
||||
rb.Push<u32>(0);
|
||||
}
|
||||
|
||||
void IApplicationFunctions::ExecuteProgram(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
[[maybe_unused]] const auto unk_1 = rp.Pop<u32>();
|
||||
[[maybe_unused]] const auto unk_2 = rp.Pop<u32>();
|
||||
const auto program_index = rp.Pop<u64>();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
system.ExecuteProgram(program_index);
|
||||
}
|
||||
|
||||
void IApplicationFunctions::ClearUserChannel(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IApplicationFunctions::UnpopToUserChannel(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IApplicationFunctions::GetPreviousProgramIndex(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
@@ -1580,22 +1617,22 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe
|
||||
rb.PushCopyObjects(friend_invitation_storage_channel_event.readable);
|
||||
}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager,
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system) {
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
|
||||
Core::System& system) {
|
||||
auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel());
|
||||
// Needed on game boot
|
||||
message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
|
||||
|
||||
std::make_shared<AppletAE>(nvflinger, message_queue, system)->InstallAsService(service_manager);
|
||||
std::make_shared<AppletOE>(nvflinger, message_queue, system)->InstallAsService(service_manager);
|
||||
std::make_shared<IdleSys>()->InstallAsService(service_manager);
|
||||
std::make_shared<OMM>()->InstallAsService(service_manager);
|
||||
std::make_shared<SPSM>()->InstallAsService(service_manager);
|
||||
std::make_shared<TCAP>()->InstallAsService(service_manager);
|
||||
std::make_shared<IdleSys>(system)->InstallAsService(service_manager);
|
||||
std::make_shared<OMM>(system)->InstallAsService(service_manager);
|
||||
std::make_shared<SPSM>(system)->InstallAsService(service_manager);
|
||||
std::make_shared<TCAP>(system)->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
IHomeMenuFunctions::IHomeMenuFunctions(Kernel::KernelCore& kernel)
|
||||
: ServiceFramework("IHomeMenuFunctions"), kernel(kernel) {
|
||||
IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
|
||||
: ServiceFramework{system_, "IHomeMenuFunctions"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
|
||||
@@ -1614,7 +1651,7 @@ IHomeMenuFunctions::IHomeMenuFunctions(Kernel::KernelCore& kernel)
|
||||
RegisterHandlers(functions);
|
||||
|
||||
pop_from_general_channel_event = Kernel::WritableEvent::CreateEventPair(
|
||||
kernel, "IHomeMenuFunctions:PopFromGeneralChannelEvent");
|
||||
system.Kernel(), "IHomeMenuFunctions:PopFromGeneralChannelEvent");
|
||||
}
|
||||
|
||||
IHomeMenuFunctions::~IHomeMenuFunctions() = default;
|
||||
@@ -1634,7 +1671,8 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext
|
||||
rb.PushCopyObjects(pop_from_general_channel_event.readable);
|
||||
}
|
||||
|
||||
IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") {
|
||||
IGlobalStateController::IGlobalStateController(Core::System& system_)
|
||||
: ServiceFramework{system_, "IGlobalStateController"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestToEnterSleep"},
|
||||
@@ -1657,7 +1695,8 @@ IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStat
|
||||
|
||||
IGlobalStateController::~IGlobalStateController() = default;
|
||||
|
||||
IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreator") {
|
||||
IApplicationCreator::IApplicationCreator(Core::System& system_)
|
||||
: ServiceFramework{system_, "IApplicationCreator"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CreateApplication"},
|
||||
@@ -1672,8 +1711,8 @@ IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreat
|
||||
|
||||
IApplicationCreator::~IApplicationCreator() = default;
|
||||
|
||||
IProcessWindingController::IProcessWindingController()
|
||||
: ServiceFramework("IProcessWindingController") {
|
||||
IProcessWindingController::IProcessWindingController(Core::System& system_)
|
||||
: ServiceFramework{system_, "IProcessWindingController"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetLaunchReason"},
|
||||
|
||||
@@ -77,13 +77,11 @@ public:
|
||||
private:
|
||||
void GetAppletResourceUserId(Kernel::HLERequestContext& ctx);
|
||||
void AcquireForegroundRights(Kernel::HLERequestContext& ctx);
|
||||
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
class IAudioController final : public ServiceFramework<IAudioController> {
|
||||
public:
|
||||
IAudioController();
|
||||
explicit IAudioController(Core::System& system_);
|
||||
~IAudioController() override;
|
||||
|
||||
private:
|
||||
@@ -109,20 +107,19 @@ private:
|
||||
|
||||
class IDisplayController final : public ServiceFramework<IDisplayController> {
|
||||
public:
|
||||
IDisplayController();
|
||||
explicit IDisplayController(Core::System& system_);
|
||||
~IDisplayController() override;
|
||||
};
|
||||
|
||||
class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
|
||||
public:
|
||||
IDebugFunctions();
|
||||
explicit IDebugFunctions(Core::System& system_);
|
||||
~IDebugFunctions() override;
|
||||
};
|
||||
|
||||
class ISelfController final : public ServiceFramework<ISelfController> {
|
||||
public:
|
||||
explicit ISelfController(Core::System& system_,
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger_);
|
||||
explicit ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_);
|
||||
~ISelfController() override;
|
||||
|
||||
private:
|
||||
@@ -155,8 +152,7 @@ private:
|
||||
Disable = 2,
|
||||
};
|
||||
|
||||
Core::System& system;
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
|
||||
NVFlinger::NVFlinger& nvflinger;
|
||||
Kernel::EventPair launchable_event;
|
||||
Kernel::EventPair accumulated_suspended_tick_changed_event;
|
||||
|
||||
@@ -168,8 +164,8 @@ private:
|
||||
|
||||
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
|
||||
public:
|
||||
explicit ICommonStateGetter(Core::System& system,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue);
|
||||
explicit ICommonStateGetter(Core::System& system_,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue_);
|
||||
~ICommonStateGetter() override;
|
||||
|
||||
private:
|
||||
@@ -197,7 +193,6 @@ private:
|
||||
void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
|
||||
void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
|
||||
|
||||
Core::System& system;
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue;
|
||||
bool vr_mode_state{};
|
||||
};
|
||||
@@ -212,7 +207,7 @@ public:
|
||||
|
||||
class IStorage final : public ServiceFramework<IStorage> {
|
||||
public:
|
||||
explicit IStorage(std::vector<u8>&& buffer);
|
||||
explicit IStorage(Core::System& system_, std::vector<u8>&& buffer);
|
||||
~IStorage() override;
|
||||
|
||||
std::vector<u8>& GetData() {
|
||||
@@ -236,7 +231,7 @@ private:
|
||||
|
||||
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
|
||||
public:
|
||||
explicit IStorageAccessor(IStorage& backing);
|
||||
explicit IStorageAccessor(Core::System& system_, IStorage& backing_);
|
||||
~IStorageAccessor() override;
|
||||
|
||||
private:
|
||||
@@ -256,8 +251,6 @@ private:
|
||||
void CreateLibraryApplet(Kernel::HLERequestContext& ctx);
|
||||
void CreateStorage(Kernel::HLERequestContext& ctx);
|
||||
void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx);
|
||||
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
|
||||
@@ -288,6 +281,9 @@ private:
|
||||
void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx);
|
||||
void QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx);
|
||||
void QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx);
|
||||
void ExecuteProgram(Kernel::HLERequestContext& ctx);
|
||||
void ClearUserChannel(Kernel::HLERequestContext& ctx);
|
||||
void UnpopToUserChannel(Kernel::HLERequestContext& ctx);
|
||||
void GetPreviousProgramIndex(Kernel::HLERequestContext& ctx);
|
||||
void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
|
||||
void GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx);
|
||||
@@ -297,12 +293,11 @@ private:
|
||||
s32 previous_program_index{-1};
|
||||
Kernel::EventPair gpu_error_detected_event;
|
||||
Kernel::EventPair friend_invitation_storage_channel_event;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
|
||||
public:
|
||||
explicit IHomeMenuFunctions(Kernel::KernelCore& kernel);
|
||||
explicit IHomeMenuFunctions(Core::System& system_);
|
||||
~IHomeMenuFunctions() override;
|
||||
|
||||
private:
|
||||
@@ -310,29 +305,28 @@ private:
|
||||
void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx);
|
||||
|
||||
Kernel::EventPair pop_from_general_channel_event;
|
||||
Kernel::KernelCore& kernel;
|
||||
};
|
||||
|
||||
class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {
|
||||
public:
|
||||
IGlobalStateController();
|
||||
explicit IGlobalStateController(Core::System& system_);
|
||||
~IGlobalStateController() override;
|
||||
};
|
||||
|
||||
class IApplicationCreator final : public ServiceFramework<IApplicationCreator> {
|
||||
public:
|
||||
IApplicationCreator();
|
||||
explicit IApplicationCreator(Core::System& system_);
|
||||
~IApplicationCreator() override;
|
||||
};
|
||||
|
||||
class IProcessWindingController final : public ServiceFramework<IProcessWindingController> {
|
||||
public:
|
||||
IProcessWindingController();
|
||||
explicit IProcessWindingController(Core::System& system_);
|
||||
~IProcessWindingController() override;
|
||||
};
|
||||
|
||||
/// Registers all AM services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager,
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system);
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
|
||||
Core::System& system);
|
||||
|
||||
} // namespace Service::AM
|
||||
|
||||
@@ -13,11 +13,11 @@ namespace Service::AM {
|
||||
|
||||
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
|
||||
public:
|
||||
explicit ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue,
|
||||
Core::System& system)
|
||||
: ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)),
|
||||
msg_queue(std::move(msg_queue)), system(system) {
|
||||
explicit ILibraryAppletProxy(NVFlinger::NVFlinger& nvflinger_,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue_,
|
||||
Core::System& system_)
|
||||
: ServiceFramework{system_, "ILibraryAppletProxy"}, nvflinger{nvflinger_},
|
||||
msg_queue{std::move(msg_queue_)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
|
||||
@@ -66,7 +66,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IAudioController>();
|
||||
rb.PushIpcInterface<IAudioController>(system);
|
||||
}
|
||||
|
||||
void GetDisplayController(Kernel::HLERequestContext& ctx) {
|
||||
@@ -74,7 +74,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDisplayController>();
|
||||
rb.PushIpcInterface<IDisplayController>(system);
|
||||
}
|
||||
|
||||
void GetProcessWindingController(Kernel::HLERequestContext& ctx) {
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IProcessWindingController>();
|
||||
rb.PushIpcInterface<IProcessWindingController>(system);
|
||||
}
|
||||
|
||||
void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDebugFunctions>();
|
||||
rb.PushIpcInterface<IDebugFunctions>(system);
|
||||
}
|
||||
|
||||
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
|
||||
@@ -109,17 +109,17 @@ private:
|
||||
rb.PushIpcInterface<IApplicationFunctions>(system);
|
||||
}
|
||||
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
|
||||
NVFlinger::NVFlinger& nvflinger;
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
|
||||
public:
|
||||
explicit ISystemAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system)
|
||||
: ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)),
|
||||
msg_queue(std::move(msg_queue)), system(system) {
|
||||
explicit ISystemAppletProxy(NVFlinger::NVFlinger& nvflinger_,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue_,
|
||||
Core::System& system_)
|
||||
: ServiceFramework{system_, "ISystemAppletProxy"}, nvflinger{nvflinger_},
|
||||
msg_queue{std::move(msg_queue_)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
|
||||
@@ -170,7 +170,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IAudioController>();
|
||||
rb.PushIpcInterface<IAudioController>(system);
|
||||
}
|
||||
|
||||
void GetDisplayController(Kernel::HLERequestContext& ctx) {
|
||||
@@ -178,7 +178,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDisplayController>();
|
||||
rb.PushIpcInterface<IDisplayController>(system);
|
||||
}
|
||||
|
||||
void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
|
||||
@@ -186,7 +186,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDebugFunctions>();
|
||||
rb.PushIpcInterface<IDebugFunctions>(system);
|
||||
}
|
||||
|
||||
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
|
||||
@@ -202,7 +202,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IHomeMenuFunctions>(system.Kernel());
|
||||
rb.PushIpcInterface<IHomeMenuFunctions>(system);
|
||||
}
|
||||
|
||||
void GetGlobalStateController(Kernel::HLERequestContext& ctx) {
|
||||
@@ -210,7 +210,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IGlobalStateController>();
|
||||
rb.PushIpcInterface<IGlobalStateController>(system);
|
||||
}
|
||||
|
||||
void GetApplicationCreator(Kernel::HLERequestContext& ctx) {
|
||||
@@ -218,11 +218,11 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IApplicationCreator>();
|
||||
rb.PushIpcInterface<IApplicationCreator>(system);
|
||||
}
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
|
||||
|
||||
NVFlinger::NVFlinger& nvflinger;
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) {
|
||||
@@ -249,10 +249,10 @@ void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
|
||||
rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue, system);
|
||||
}
|
||||
|
||||
AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system)
|
||||
: ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)),
|
||||
msg_queue(std::move(msg_queue)), system(system) {
|
||||
AppletAE::AppletAE(NVFlinger::NVFlinger& nvflinger_, std::shared_ptr<AppletMessageQueue> msg_queue_,
|
||||
Core::System& system_)
|
||||
: ServiceFramework{system_, "appletAE"}, nvflinger{nvflinger_}, msg_queue{
|
||||
std::move(msg_queue_)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"},
|
||||
|
||||
@@ -23,8 +23,8 @@ class AppletMessageQueue;
|
||||
|
||||
class AppletAE final : public ServiceFramework<AppletAE> {
|
||||
public:
|
||||
explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system);
|
||||
explicit AppletAE(NVFlinger::NVFlinger& nvflinger_,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_);
|
||||
~AppletAE() override;
|
||||
|
||||
const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
|
||||
@@ -34,9 +34,8 @@ private:
|
||||
void OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx);
|
||||
void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
|
||||
NVFlinger::NVFlinger& nvflinger;
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
} // namespace AM
|
||||
|
||||
@@ -12,10 +12,11 @@ namespace Service::AM {
|
||||
|
||||
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
|
||||
public:
|
||||
explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system)
|
||||
: ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)),
|
||||
msg_queue(std::move(msg_queue)), system(system) {
|
||||
explicit IApplicationProxy(NVFlinger::NVFlinger& nvflinger_,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue_,
|
||||
Core::System& system_)
|
||||
: ServiceFramework{system_, "IApplicationProxy"}, nvflinger{nvflinger_},
|
||||
msg_queue{std::move(msg_queue_)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"},
|
||||
@@ -39,7 +40,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IAudioController>();
|
||||
rb.PushIpcInterface<IAudioController>(system);
|
||||
}
|
||||
|
||||
void GetDisplayController(Kernel::HLERequestContext& ctx) {
|
||||
@@ -47,7 +48,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDisplayController>();
|
||||
rb.PushIpcInterface<IDisplayController>(system);
|
||||
}
|
||||
|
||||
void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
|
||||
@@ -55,7 +56,7 @@ private:
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDebugFunctions>();
|
||||
rb.PushIpcInterface<IDebugFunctions>(system);
|
||||
}
|
||||
|
||||
void GetWindowController(Kernel::HLERequestContext& ctx) {
|
||||
@@ -98,9 +99,8 @@ private:
|
||||
rb.PushIpcInterface<IApplicationFunctions>(system);
|
||||
}
|
||||
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
|
||||
NVFlinger::NVFlinger& nvflinger;
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
|
||||
@@ -111,10 +111,10 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
|
||||
rb.PushIpcInterface<IApplicationProxy>(nvflinger, msg_queue, system);
|
||||
}
|
||||
|
||||
AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system)
|
||||
: ServiceFramework("appletOE"), nvflinger(std::move(nvflinger)),
|
||||
msg_queue(std::move(msg_queue)), system(system) {
|
||||
AppletOE::AppletOE(NVFlinger::NVFlinger& nvflinger_, std::shared_ptr<AppletMessageQueue> msg_queue_,
|
||||
Core::System& system_)
|
||||
: ServiceFramework{system_, "appletOE"}, nvflinger{nvflinger_}, msg_queue{
|
||||
std::move(msg_queue_)} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"},
|
||||
};
|
||||
|
||||
@@ -23,8 +23,8 @@ class AppletMessageQueue;
|
||||
|
||||
class AppletOE final : public ServiceFramework<AppletOE> {
|
||||
public:
|
||||
explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue, Core::System& system);
|
||||
explicit AppletOE(NVFlinger::NVFlinger& nvflinger_,
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_);
|
||||
~AppletOE() override;
|
||||
|
||||
const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
|
||||
@@ -32,9 +32,8 @@ public:
|
||||
private:
|
||||
void OpenApplicationProxy(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
|
||||
NVFlinger::NVFlinger& nvflinger;
|
||||
std::shared_ptr<AppletMessageQueue> msg_queue;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
} // namespace AM
|
||||
|
||||
@@ -46,7 +46,7 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
|
||||
}
|
||||
|
||||
Controller::Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_)
|
||||
: Applet{system_.Kernel()}, frontend(frontend_) {}
|
||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
||||
|
||||
Controller::~Controller() = default;
|
||||
|
||||
@@ -245,7 +245,7 @@ void Controller::ConfigurationComplete() {
|
||||
complete = true;
|
||||
out_data = std::vector<u8>(sizeof(ControllerSupportResultInfo));
|
||||
std::memcpy(out_data.data(), &result_info, out_data.size());
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(out_data)));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
|
||||
broker.SignalStateChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ public:
|
||||
|
||||
private:
|
||||
const Core::Frontend::ControllerApplet& frontend;
|
||||
Core::System& system;
|
||||
|
||||
ControllerAppletVersion controller_applet_version;
|
||||
ControllerSupportArgPrivate controller_private_arg;
|
||||
|
||||
@@ -87,7 +87,7 @@ ResultCode Decode64BitError(u64 error) {
|
||||
} // Anonymous namespace
|
||||
|
||||
Error::Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_)
|
||||
: Applet{system_.Kernel()}, frontend(frontend_), system{system_} {}
|
||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
||||
|
||||
Error::~Error() = default;
|
||||
|
||||
@@ -186,7 +186,7 @@ void Error::Execute() {
|
||||
|
||||
void Error::DisplayCompleted() {
|
||||
complete = true;
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>{}));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{}));
|
||||
broker.SignalStateChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
|
||||
}
|
||||
|
||||
Auth::Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_)
|
||||
: Applet{system_.Kernel()}, frontend(frontend_) {}
|
||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
||||
|
||||
Auth::~Auth() = default;
|
||||
|
||||
@@ -135,8 +135,8 @@ void Auth::Execute() {
|
||||
}
|
||||
}
|
||||
|
||||
void Auth::AuthFinished(bool successful) {
|
||||
this->successful = successful;
|
||||
void Auth::AuthFinished(bool is_successful) {
|
||||
this->successful = is_successful;
|
||||
|
||||
struct Return {
|
||||
ResultCode result_code;
|
||||
@@ -148,12 +148,12 @@ void Auth::AuthFinished(bool successful) {
|
||||
std::vector<u8> out(sizeof(Return));
|
||||
std::memcpy(out.data(), &return_, sizeof(Return));
|
||||
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(out)));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out)));
|
||||
broker.SignalStateChanged();
|
||||
}
|
||||
|
||||
PhotoViewer::PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_)
|
||||
: Applet{system_.Kernel()}, frontend(frontend_), system{system_} {}
|
||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
||||
|
||||
PhotoViewer::~PhotoViewer() = default;
|
||||
|
||||
@@ -198,12 +198,12 @@ void PhotoViewer::Execute() {
|
||||
}
|
||||
|
||||
void PhotoViewer::ViewFinished() {
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>{}));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{}));
|
||||
broker.SignalStateChanged();
|
||||
}
|
||||
|
||||
StubApplet::StubApplet(Core::System& system_, AppletId id_)
|
||||
: Applet{system_.Kernel()}, id(id_), system{system_} {}
|
||||
: Applet{system_.Kernel()}, id{id_}, system{system_} {}
|
||||
|
||||
StubApplet::~StubApplet() = default;
|
||||
|
||||
@@ -234,8 +234,9 @@ void StubApplet::ExecuteInteractive() {
|
||||
LOG_WARNING(Service_AM, "called (STUBBED)");
|
||||
LogCurrentStorage(broker, "ExecuteInteractive");
|
||||
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>(0x1000)));
|
||||
broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(std::vector<u8>(0x1000)));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
|
||||
broker.PushInteractiveDataFromApplet(
|
||||
std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
|
||||
broker.SignalStateChanged();
|
||||
}
|
||||
|
||||
@@ -243,8 +244,9 @@ void StubApplet::Execute() {
|
||||
LOG_WARNING(Service_AM, "called (STUBBED)");
|
||||
LogCurrentStorage(broker, "Execute");
|
||||
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>(0x1000)));
|
||||
broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(std::vector<u8>(0x1000)));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
|
||||
broker.PushInteractiveDataFromApplet(
|
||||
std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
|
||||
broker.SignalStateChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,11 @@ public:
|
||||
void ExecuteInteractive() override;
|
||||
void Execute() override;
|
||||
|
||||
void AuthFinished(bool successful = true);
|
||||
void AuthFinished(bool is_successful = true);
|
||||
|
||||
private:
|
||||
Core::Frontend::ParentalControlsApplet& frontend;
|
||||
Core::System& system;
|
||||
bool complete = false;
|
||||
bool successful = false;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
|
||||
|
||||
ProfileSelect::ProfileSelect(Core::System& system_,
|
||||
const Core::Frontend::ProfileSelectApplet& frontend_)
|
||||
: Applet{system_.Kernel()}, frontend(frontend_) {}
|
||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
||||
|
||||
ProfileSelect::~ProfileSelect() = default;
|
||||
|
||||
@@ -50,7 +50,7 @@ void ProfileSelect::ExecuteInteractive() {
|
||||
|
||||
void ProfileSelect::Execute() {
|
||||
if (complete) {
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(final_data)));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
|
||||
|
||||
final_data = std::vector<u8>(sizeof(UserSelectionOutput));
|
||||
std::memcpy(final_data.data(), &output, final_data.size());
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(final_data)));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
|
||||
broker.SignalStateChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ private:
|
||||
bool complete = false;
|
||||
ResultCode status = RESULT_SUCCESS;
|
||||
std::vector<u8> final_data;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
} // namespace Service::AM::Applets
|
||||
|
||||
@@ -53,7 +53,7 @@ static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters(
|
||||
|
||||
SoftwareKeyboard::SoftwareKeyboard(Core::System& system_,
|
||||
const Core::Frontend::SoftwareKeyboardApplet& frontend_)
|
||||
: Applet{system_.Kernel()}, frontend(frontend_) {}
|
||||
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
|
||||
|
||||
SoftwareKeyboard::~SoftwareKeyboard() = default;
|
||||
|
||||
@@ -122,7 +122,7 @@ void SoftwareKeyboard::ExecuteInteractive() {
|
||||
|
||||
switch (request) {
|
||||
case Request::Calc: {
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::vector<u8>{1}));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{1}));
|
||||
broker.SignalStateChanged();
|
||||
break;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ void SoftwareKeyboard::ExecuteInteractive() {
|
||||
|
||||
void SoftwareKeyboard::Execute() {
|
||||
if (complete) {
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(final_data)));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
|
||||
broker.SignalStateChanged();
|
||||
return;
|
||||
}
|
||||
@@ -179,15 +179,17 @@ void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
|
||||
final_data = output_main;
|
||||
|
||||
if (complete) {
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(output_main)));
|
||||
broker.PushNormalDataFromApplet(
|
||||
std::make_shared<IStorage>(system, std::move(output_main)));
|
||||
broker.SignalStateChanged();
|
||||
} else {
|
||||
broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(std::move(output_sub)));
|
||||
broker.PushInteractiveDataFromApplet(
|
||||
std::make_shared<IStorage>(system, std::move(output_sub)));
|
||||
}
|
||||
} else {
|
||||
output_main[0] = 1;
|
||||
complete = true;
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(output_main)));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(output_main)));
|
||||
broker.SignalStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ private:
|
||||
bool complete = false;
|
||||
bool is_inline = false;
|
||||
std::vector<u8> final_data;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
} // namespace Service::AM::Applets
|
||||
|
||||
@@ -290,7 +290,7 @@ void WebBrowser::Finalize() {
|
||||
std::vector<u8> data(sizeof(WebCommonReturnValue));
|
||||
std::memcpy(data.data(), &out, sizeof(WebCommonReturnValue));
|
||||
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(std::move(data)));
|
||||
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(data)));
|
||||
broker.SignalStateChanged();
|
||||
|
||||
if (!temporary_dir.empty() && Common::FS::IsDirectory(temporary_dir)) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
IdleSys::IdleSys() : ServiceFramework{"idle:sys"} {
|
||||
IdleSys::IdleSys(Core::System& system_) : ServiceFramework{system_, "idle:sys"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetAutoPowerDownEvent"},
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
class IdleSys final : public ServiceFramework<IdleSys> {
|
||||
public:
|
||||
explicit IdleSys();
|
||||
explicit IdleSys(Core::System& system_);
|
||||
~IdleSys() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
OMM::OMM() : ServiceFramework{"omm"} {
|
||||
OMM::OMM(Core::System& system_) : ServiceFramework{system_, "omm"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetOperationMode"},
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
class OMM final : public ServiceFramework<OMM> {
|
||||
public:
|
||||
explicit OMM();
|
||||
explicit OMM(Core::System& system_);
|
||||
~OMM() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
SPSM::SPSM() : ServiceFramework{"spsm"} {
|
||||
SPSM::SPSM(Core::System& system_) : ServiceFramework{system_, "spsm"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetState"},
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
class SPSM final : public ServiceFramework<SPSM> {
|
||||
public:
|
||||
explicit SPSM();
|
||||
explicit SPSM(Core::System& system_);
|
||||
~SPSM() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
TCAP::TCAP() : ServiceFramework{"tcap"} {
|
||||
TCAP::TCAP(Core::System& system_) : ServiceFramework{system_, "tcap"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetContinuousHighSkinTemperatureEvent"},
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
class TCAP final : public ServiceFramework<TCAP> {
|
||||
public:
|
||||
explicit TCAP();
|
||||
explicit TCAP(Core::System& system_);
|
||||
~TCAP() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) {
|
||||
return add_on_content;
|
||||
}
|
||||
|
||||
AOC_U::AOC_U(Core::System& system)
|
||||
: ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs(system)), system(system) {
|
||||
AOC_U::AOC_U(Core::System& system_)
|
||||
: ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CountAddOnContentByApplicationId"},
|
||||
@@ -164,7 +164,8 @@ void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
const auto title_id = system.CurrentProcess()->GetTitleID();
|
||||
FileSys::PatchManager pm{title_id};
|
||||
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
|
||||
const auto res = pm.GetControlMetadata();
|
||||
if (res.first == nullptr) {
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Kernel {
|
||||
class WritableEvent;
|
||||
}
|
||||
@@ -26,7 +30,6 @@ private:
|
||||
|
||||
std::vector<u64> add_on_content;
|
||||
Kernel::EventPair aoc_change_event;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
/// Registers all AOC services with the specified service manager.
|
||||
|
||||
@@ -14,13 +14,14 @@ Module::~Module() = default;
|
||||
|
||||
void InstallInterfaces(Core::System& system) {
|
||||
auto module_ = std::make_shared<Module>();
|
||||
std::make_shared<APM>(module_, system.GetAPMController(), "apm")
|
||||
std::make_shared<APM>(system, module_, system.GetAPMController(), "apm")
|
||||
->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<APM>(module_, system.GetAPMController(), "apm:p")
|
||||
std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:p")
|
||||
->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<APM>(module_, system.GetAPMController(), "apm:am")
|
||||
std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:am")
|
||||
->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<APM_Sys>(system, system.GetAPMController())
|
||||
->InstallAsService(system.ServiceManager());
|
||||
std::make_shared<APM_Sys>(system.GetAPMController())->InstallAsService(system.ServiceManager());
|
||||
}
|
||||
|
||||
} // namespace Service::APM
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::APM {
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ namespace Service::APM {
|
||||
|
||||
class ISession final : public ServiceFramework<ISession> {
|
||||
public:
|
||||
ISession(Controller& controller) : ServiceFramework("ISession"), controller(controller) {
|
||||
explicit ISession(Core::System& system_, Controller& controller_)
|
||||
: ServiceFramework{system_, "ISession"}, controller{controller_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
|
||||
{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
|
||||
@@ -50,8 +51,9 @@ private:
|
||||
Controller& controller;
|
||||
};
|
||||
|
||||
APM::APM(std::shared_ptr<Module> apm, Controller& controller, const char* name)
|
||||
: ServiceFramework(name), apm(std::move(apm)), controller(controller) {
|
||||
APM::APM(Core::System& system_, std::shared_ptr<Module> apm_, Controller& controller_,
|
||||
const char* name)
|
||||
: ServiceFramework{system_, name}, apm(std::move(apm_)), controller{controller_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &APM::OpenSession, "OpenSession"},
|
||||
{1, &APM::GetPerformanceMode, "GetPerformanceMode"},
|
||||
@@ -67,7 +69,7 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISession>(controller);
|
||||
rb.PushIpcInterface<ISession>(system, controller);
|
||||
}
|
||||
|
||||
void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
|
||||
@@ -77,7 +79,8 @@ void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
|
||||
rb.PushEnum(controller.GetCurrentPerformanceMode());
|
||||
}
|
||||
|
||||
APM_Sys::APM_Sys(Controller& controller) : ServiceFramework{"apm:sys"}, controller(controller) {
|
||||
APM_Sys::APM_Sys(Core::System& system_, Controller& controller_)
|
||||
: ServiceFramework{system_, "apm:sys"}, controller{controller_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestPerformanceMode"},
|
||||
@@ -101,7 +104,7 @@ void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISession>(controller);
|
||||
rb.PushIpcInterface<ISession>(system, controller);
|
||||
}
|
||||
|
||||
void APM_Sys::SetCpuBoostMode(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -13,7 +13,8 @@ class Module;
|
||||
|
||||
class APM final : public ServiceFramework<APM> {
|
||||
public:
|
||||
explicit APM(std::shared_ptr<Module> apm, Controller& controller, const char* name);
|
||||
explicit APM(Core::System& system_, std::shared_ptr<Module> apm_, Controller& controller_,
|
||||
const char* name);
|
||||
~APM() override;
|
||||
|
||||
private:
|
||||
@@ -26,7 +27,7 @@ private:
|
||||
|
||||
class APM_Sys final : public ServiceFramework<APM_Sys> {
|
||||
public:
|
||||
explicit APM_Sys(Controller& controller);
|
||||
explicit APM_Sys(Core::System& system_, Controller& controller);
|
||||
~APM_Sys() override;
|
||||
|
||||
void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
AudCtl::AudCtl() : ServiceFramework{"audctl"} {
|
||||
AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetTargetVolume"},
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
class AudCtl final : public ServiceFramework<AudCtl> {
|
||||
public:
|
||||
explicit AudCtl();
|
||||
explicit AudCtl(Core::System& system_);
|
||||
~AudCtl() override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
AudDbg::AudDbg(const char* name) : ServiceFramework{name} {
|
||||
AudDbg::AudDbg(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspendForDebug"},
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
class AudDbg final : public ServiceFramework<AudDbg> {
|
||||
public:
|
||||
explicit AudDbg(const char* name);
|
||||
explicit AudDbg(Core::System& system_, const char* name);
|
||||
~AudDbg() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
AudInA::AudInA() : ServiceFramework{"audin:a"} {
|
||||
AudInA::AudInA(Core::System& system_) : ServiceFramework{system_, "audin:a"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "RequestSuspendAudioIns"},
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
class AudInA final : public ServiceFramework<AudInA> {
|
||||
public:
|
||||
explicit AudInA();
|
||||
explicit AudInA(Core::System& system_);
|
||||
~AudInA() override;
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user