Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9a694d7cb | ||
|
|
df9f236ad3 |
No files matched your search
@@ -9,7 +9,6 @@ stages:
|
||||
displayName: 'build'
|
||||
jobs:
|
||||
- job: build
|
||||
timeoutInMinutes: 120
|
||||
displayName: 'windows-msvc'
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
@@ -44,16 +44,6 @@ add_library(audio_core STATIC
|
||||
|
||||
create_target_directory_groups(audio_core)
|
||||
|
||||
if (NOT MSVC)
|
||||
target_compile_options(audio_core PRIVATE
|
||||
-Werror=ignored-qualifiers
|
||||
-Werror=implicit-fallthrough
|
||||
-Werror=reorder
|
||||
-Werror=sign-compare
|
||||
-Werror=unused-variable
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(audio_core PUBLIC common core)
|
||||
target_link_libraries(audio_core PRIVATE SoundTouch)
|
||||
|
||||
|
||||
@@ -3,13 +3,16 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "audio_core/algorithm/interpolate.h"
|
||||
#include "audio_core/audio_out.h"
|
||||
#include "audio_core/audio_renderer.h"
|
||||
#include "audio_core/codec.h"
|
||||
#include "audio_core/common.h"
|
||||
#include "audio_core/info_updater.h"
|
||||
#include "audio_core/voice_context.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/writable_event.h"
|
||||
#include "core/memory.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/hle/kernel/object.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Core::Timing {
|
||||
|
||||
@@ -57,15 +57,15 @@ bool BehaviorInfo::IsLongSizePreDelaySupported() const {
|
||||
return AudioCommon::IsRevisionSupported(3, user_revision);
|
||||
}
|
||||
|
||||
bool BehaviorInfo::IsAudioRendererProcessingTimeLimit80PercentSupported() const {
|
||||
bool BehaviorInfo::IsAudioRenererProcessingTimeLimit80PercentSupported() const {
|
||||
return AudioCommon::IsRevisionSupported(5, user_revision);
|
||||
}
|
||||
|
||||
bool BehaviorInfo::IsAudioRendererProcessingTimeLimit75PercentSupported() const {
|
||||
bool BehaviorInfo::IsAudioRenererProcessingTimeLimit75PercentSupported() const {
|
||||
return AudioCommon::IsRevisionSupported(4, user_revision);
|
||||
}
|
||||
|
||||
bool BehaviorInfo::IsAudioRendererProcessingTimeLimit70PercentSupported() const {
|
||||
bool BehaviorInfo::IsAudioRenererProcessingTimeLimit70PercentSupported() const {
|
||||
return AudioCommon::IsRevisionSupported(1, user_revision);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,9 +49,9 @@ public:
|
||||
bool IsAdpcmLoopContextBugFixed() const;
|
||||
bool IsSplitterSupported() const;
|
||||
bool IsLongSizePreDelaySupported() const;
|
||||
bool IsAudioRendererProcessingTimeLimit80PercentSupported() const;
|
||||
bool IsAudioRendererProcessingTimeLimit75PercentSupported() const;
|
||||
bool IsAudioRendererProcessingTimeLimit70PercentSupported() const;
|
||||
bool IsAudioRenererProcessingTimeLimit80PercentSupported() const;
|
||||
bool IsAudioRenererProcessingTimeLimit75PercentSupported() const;
|
||||
bool IsAudioRenererProcessingTimeLimit70PercentSupported() const;
|
||||
bool IsElapsedFrameCountSupported() const;
|
||||
bool IsMemoryPoolForceMappingEnabled() const;
|
||||
bool IsFlushVoiceWaveBuffersSupported() const;
|
||||
|
||||
@@ -16,9 +16,8 @@ std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM
|
||||
|
||||
constexpr std::size_t FRAME_LEN = 8;
|
||||
constexpr std::size_t SAMPLES_PER_FRAME = 14;
|
||||
static constexpr std::array<int, 16> SIGNED_NIBBLES{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1,
|
||||
};
|
||||
constexpr std::array<int, 16> SIGNED_NIBBLES = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
|
||||
|
||||
const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME;
|
||||
const std::size_t ret_size =
|
||||
|
||||
@@ -38,7 +38,7 @@ using ADPCM_Coeff = std::array<s16, 16>;
|
||||
* @param state ADPCM state, this is updated with new state
|
||||
* @return Decoded stereo signed PCM16 data, sample_count in length
|
||||
*/
|
||||
std::vector<s16> DecodeADPCM(const u8* data, std::size_t size, const ADPCM_Coeff& coeff,
|
||||
std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff,
|
||||
ADPCMState& state);
|
||||
|
||||
}; // namespace AudioCore::Codec
|
||||
@@ -152,7 +152,7 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) {
|
||||
if (!destination_data->IsConfigured()) {
|
||||
continue;
|
||||
}
|
||||
if (destination_data->GetMixId() >= static_cast<int>(mix_context.GetCount())) {
|
||||
if (destination_data->GetMixId() >= mix_context.GetCount()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* inf
|
||||
GetMixBuffer(output_index), worker_params.sample_count, offset, write_count);
|
||||
memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP));
|
||||
|
||||
if (samples_read != static_cast<int>(worker_params.sample_count) &&
|
||||
if (samples_read != worker_params.sample_count &&
|
||||
samples_read <= params.sample_count) {
|
||||
std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read);
|
||||
}
|
||||
@@ -611,8 +611,7 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) {
|
||||
const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId());
|
||||
const auto& dest_in_params = dest_mix.GetInParams();
|
||||
const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset;
|
||||
for (std::size_t i = 0; i < static_cast<std::size_t>(dest_in_params.buffer_count);
|
||||
i++) {
|
||||
for (std::size_t i = 0; i < dest_in_params.buffer_count; i++) {
|
||||
const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i);
|
||||
if (mixed_volume != 0.0f) {
|
||||
GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume,
|
||||
@@ -705,7 +704,7 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
|
||||
std::vector<s16> buffer(samples_processed * channel_count);
|
||||
memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16));
|
||||
|
||||
for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
|
||||
for (std::size_t i = 0; i < samples_processed; i++) {
|
||||
sample_buffer[mix_offset + i] = buffer[i * channel_count + channel];
|
||||
}
|
||||
}
|
||||
@@ -727,9 +726,8 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
|
||||
return 0;
|
||||
}
|
||||
|
||||
static constexpr std::array<int, 16> SIGNED_NIBBLES{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1,
|
||||
};
|
||||
constexpr std::array<int, 16> SIGNED_NIBBLES = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
|
||||
|
||||
constexpr std::size_t FRAME_LEN = 8;
|
||||
constexpr std::size_t NIBBLES_PER_SAMPLE = 16;
|
||||
@@ -791,7 +789,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
|
||||
position_in_frame += 2;
|
||||
|
||||
// Decode entire frame
|
||||
if (remaining_samples >= static_cast<int>(SAMPLES_PER_FRAME)) {
|
||||
if (remaining_samples >= SAMPLES_PER_FRAME) {
|
||||
for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
|
||||
|
||||
// Sample 1
|
||||
@@ -868,6 +866,7 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
|
||||
const auto resample_rate = static_cast<s32>(
|
||||
static_cast<float>(in_params.sample_rate) / static_cast<float>(target_sample_rate) *
|
||||
static_cast<float>(static_cast<s32>(in_params.pitch * 32768.0f)));
|
||||
auto* output_base = output;
|
||||
if (dsp_state.fraction + sample_count * resample_rate >
|
||||
static_cast<s32>(SCALED_MIX_BUFFER_SIZE - 4ULL)) {
|
||||
return;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <array>
|
||||
#include "audio_core/common.h"
|
||||
#include "audio_core/voice_context.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Core::Memory {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
|
||||
@@ -192,8 +192,8 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels,
|
||||
|
||||
long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
|
||||
void* output_buffer, long num_frames) {
|
||||
auto* impl = static_cast<CubebSinkStream*>(user_data);
|
||||
auto* buffer = static_cast<u8*>(output_buffer);
|
||||
CubebSinkStream* impl = static_cast<CubebSinkStream*>(user_data);
|
||||
u8* buffer = reinterpret_cast<u8*>(output_buffer);
|
||||
|
||||
if (!impl) {
|
||||
return {};
|
||||
|
||||
@@ -184,19 +184,19 @@ void EffectAuxInfo::UpdateForCommandGeneration() {
|
||||
}
|
||||
}
|
||||
|
||||
VAddr EffectAuxInfo::GetSendInfo() const {
|
||||
const VAddr EffectAuxInfo::GetSendInfo() const {
|
||||
return send_info;
|
||||
}
|
||||
|
||||
VAddr EffectAuxInfo::GetSendBuffer() const {
|
||||
const VAddr EffectAuxInfo::GetSendBuffer() const {
|
||||
return send_buffer;
|
||||
}
|
||||
|
||||
VAddr EffectAuxInfo::GetRecvInfo() const {
|
||||
const VAddr EffectAuxInfo::GetRecvInfo() const {
|
||||
return recv_info;
|
||||
}
|
||||
|
||||
VAddr EffectAuxInfo::GetRecvBuffer() const {
|
||||
const VAddr EffectAuxInfo::GetRecvBuffer() const {
|
||||
return recv_buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,13 +166,13 @@ public:
|
||||
std::array<u8, 0xa0> raw;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(InParams) == 0xc0, "InParams is an invalid size");
|
||||
static_assert(sizeof(EffectInfo::InParams) == 0xc0, "InParams is an invalid size");
|
||||
|
||||
struct OutParams {
|
||||
UsageStatus status{};
|
||||
INSERT_PADDING_BYTES(15);
|
||||
};
|
||||
static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size");
|
||||
static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size");
|
||||
};
|
||||
|
||||
struct AuxAddress {
|
||||
@@ -184,8 +184,8 @@ struct AuxAddress {
|
||||
|
||||
class EffectBase {
|
||||
public:
|
||||
explicit EffectBase(EffectType effect_type);
|
||||
virtual ~EffectBase();
|
||||
EffectBase(EffectType effect_type);
|
||||
~EffectBase();
|
||||
|
||||
virtual void Update(EffectInfo::InParams& in_params) = 0;
|
||||
virtual void UpdateForCommandGeneration() = 0;
|
||||
@@ -206,7 +206,8 @@ protected:
|
||||
template <typename T>
|
||||
class EffectGeneric : public EffectBase {
|
||||
public:
|
||||
explicit EffectGeneric(EffectType effect_type) : EffectBase(effect_type) {}
|
||||
EffectGeneric(EffectType effect_type) : EffectBase::EffectBase(effect_type) {}
|
||||
~EffectGeneric() = default;
|
||||
|
||||
T& GetParams() {
|
||||
return internal_params;
|
||||
@@ -223,7 +224,7 @@ private:
|
||||
class EffectStubbed : public EffectBase {
|
||||
public:
|
||||
explicit EffectStubbed();
|
||||
~EffectStubbed() override;
|
||||
~EffectStubbed();
|
||||
|
||||
void Update(EffectInfo::InParams& in_params) override;
|
||||
void UpdateForCommandGeneration() override;
|
||||
@@ -232,7 +233,7 @@ public:
|
||||
class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> {
|
||||
public:
|
||||
explicit EffectI3dl2Reverb();
|
||||
~EffectI3dl2Reverb() override;
|
||||
~EffectI3dl2Reverb();
|
||||
|
||||
void Update(EffectInfo::InParams& in_params) override;
|
||||
void UpdateForCommandGeneration() override;
|
||||
@@ -244,7 +245,7 @@ private:
|
||||
class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> {
|
||||
public:
|
||||
explicit EffectBiquadFilter();
|
||||
~EffectBiquadFilter() override;
|
||||
~EffectBiquadFilter();
|
||||
|
||||
void Update(EffectInfo::InParams& in_params) override;
|
||||
void UpdateForCommandGeneration() override;
|
||||
@@ -253,14 +254,14 @@ public:
|
||||
class EffectAuxInfo : public EffectGeneric<AuxInfo> {
|
||||
public:
|
||||
explicit EffectAuxInfo();
|
||||
~EffectAuxInfo() override;
|
||||
~EffectAuxInfo();
|
||||
|
||||
void Update(EffectInfo::InParams& in_params) override;
|
||||
void UpdateForCommandGeneration() override;
|
||||
VAddr GetSendInfo() const;
|
||||
VAddr GetSendBuffer() const;
|
||||
VAddr GetRecvInfo() const;
|
||||
VAddr GetRecvBuffer() const;
|
||||
const VAddr GetSendInfo() const;
|
||||
const VAddr GetSendBuffer() const;
|
||||
const VAddr GetRecvInfo() const;
|
||||
const VAddr GetRecvBuffer() const;
|
||||
|
||||
private:
|
||||
VAddr send_info{};
|
||||
@@ -274,7 +275,7 @@ private:
|
||||
class EffectDelay : public EffectGeneric<DelayParams> {
|
||||
public:
|
||||
explicit EffectDelay();
|
||||
~EffectDelay() override;
|
||||
~EffectDelay();
|
||||
|
||||
void Update(EffectInfo::InParams& in_params) override;
|
||||
void UpdateForCommandGeneration() override;
|
||||
@@ -286,7 +287,7 @@ private:
|
||||
class EffectBufferMixer : public EffectGeneric<BufferMixerParams> {
|
||||
public:
|
||||
explicit EffectBufferMixer();
|
||||
~EffectBufferMixer() override;
|
||||
~EffectBufferMixer();
|
||||
|
||||
void Update(EffectInfo::InParams& in_params) override;
|
||||
void UpdateForCommandGeneration() override;
|
||||
@@ -295,7 +296,7 @@ public:
|
||||
class EffectReverb : public EffectGeneric<ReverbParams> {
|
||||
public:
|
||||
explicit EffectReverb();
|
||||
~EffectReverb() override;
|
||||
~EffectReverb();
|
||||
|
||||
void Update(EffectInfo::InParams& in_params) override;
|
||||
void UpdateForCommandGeneration() override;
|
||||
|
||||
@@ -64,6 +64,7 @@ bool InfoUpdater::UpdateBehaviorInfo(BehaviorInfo& in_behavior_info) {
|
||||
}
|
||||
|
||||
bool InfoUpdater::UpdateMemoryPools(std::vector<ServerMemoryPoolInfo>& memory_pool_info) {
|
||||
const auto force_mapping = behavior_info.IsMemoryPoolForceMappingEnabled();
|
||||
const auto memory_pool_count = memory_pool_info.size();
|
||||
const auto total_memory_pool_in = sizeof(ServerMemoryPoolInfo::InParams) * memory_pool_count;
|
||||
const auto total_memory_pool_out = sizeof(ServerMemoryPoolInfo::OutParams) * memory_pool_count;
|
||||
@@ -173,7 +174,7 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||
}
|
||||
// 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(in_params.id < voice_count);
|
||||
|
||||
// Grab our current voice info
|
||||
auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id));
|
||||
@@ -351,8 +352,8 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf
|
||||
for (std::size_t i = 0; i < mix_count; i++) {
|
||||
const auto& in = mix_in_params[i];
|
||||
total_buffer_count += in.buffer_count;
|
||||
if (static_cast<std::size_t>(in.dest_mix_id) > mix_count &&
|
||||
in.dest_mix_id != AudioCommon::NO_MIX && in.mix_id != AudioCommon::FINAL_MIX) {
|
||||
if (in.dest_mix_id > mix_count && in.dest_mix_id != AudioCommon::NO_MIX &&
|
||||
in.mix_id != AudioCommon::FINAL_MIX) {
|
||||
LOG_ERROR(
|
||||
Audio,
|
||||
"Invalid mix destination, mix_id={:X}, dest_mix_id={:X}, mix_buffer_count={:X}",
|
||||
|
||||
@@ -53,7 +53,7 @@ void MixContext::UpdateDistancesFromFinalMix() {
|
||||
auto mix_id = in_params.mix_id;
|
||||
// Needs to be referenced out of scope
|
||||
s32 distance_to_final_mix{AudioCommon::FINAL_MIX};
|
||||
for (; distance_to_final_mix < static_cast<s32>(info_count); distance_to_final_mix++) {
|
||||
for (; distance_to_final_mix < info_count; distance_to_final_mix++) {
|
||||
if (mix_id == AudioCommon::FINAL_MIX) {
|
||||
// If we're at the final mix, we're done
|
||||
break;
|
||||
@@ -77,7 +77,7 @@ void MixContext::UpdateDistancesFromFinalMix() {
|
||||
}
|
||||
|
||||
// If we're out of range for our distance, mark it as no final mix
|
||||
if (distance_to_final_mix >= static_cast<s32>(info_count)) {
|
||||
if (distance_to_final_mix >= info_count) {
|
||||
distance_to_final_mix = AudioCommon::NO_FINAL_MIX;
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ bool SplitterContext::UpdateInfo(const std::vector<u8>& input, std::size_t& inpu
|
||||
break;
|
||||
}
|
||||
|
||||
if (header.send_id < 0 || static_cast<std::size_t>(header.send_id) > info_count) {
|
||||
if (header.send_id < 0 || header.send_id > info_count) {
|
||||
LOG_ERROR(Audio, "Bad splitter data id");
|
||||
break;
|
||||
}
|
||||
@@ -348,7 +348,7 @@ bool SplitterContext::UpdateData(const std::vector<u8>& input, std::size_t& inpu
|
||||
break;
|
||||
}
|
||||
|
||||
if (header.splitter_id < 0 || static_cast<std::size_t>(header.splitter_id) > data_count) {
|
||||
if (header.splitter_id < 0 || header.splitter_id > data_count) {
|
||||
LOG_ERROR(Audio, "Bad splitter data id");
|
||||
break;
|
||||
}
|
||||
@@ -434,7 +434,7 @@ const std::vector<s32>& NodeStates::GetIndexList() const {
|
||||
}
|
||||
|
||||
void NodeStates::PushTsortResult(s32 index) {
|
||||
ASSERT(index < static_cast<s32>(node_count));
|
||||
ASSERT(index < node_count);
|
||||
index_list[index_pos++] = index;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/core_timing_util.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
@@ -488,11 +488,11 @@ s32 VoiceContext::DecodePcm16(s32* output_buffer, ServerWaveBuffer* wave_buffer,
|
||||
|
||||
// Fast path
|
||||
if (channel_count == 1) {
|
||||
for (std::ptrdiff_t i = 0; i < samples_processed; i++) {
|
||||
for (std::size_t i = 0; i < samples_processed; i++) {
|
||||
output_buffer[i] = buffer_data[i];
|
||||
}
|
||||
} else {
|
||||
for (std::ptrdiff_t i = 0; i < samples_processed; i++) {
|
||||
for (std::size_t i = 0; i < samples_processed; i++) {
|
||||
output_buffer[i] = buffer_data[i * channel_count + channel];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Common {
|
||||
using base_timer = std::chrono::steady_clock;
|
||||
using base_time_point = std::chrono::time_point<base_timer>;
|
||||
|
||||
class StandardWallClock final : public WallClock {
|
||||
class StandardWallClock : public WallClock {
|
||||
public:
|
||||
StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency)
|
||||
: WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) {
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace Common {
|
||||
|
||||
class WallClock {
|
||||
public:
|
||||
virtual ~WallClock() = default;
|
||||
|
||||
/// Returns current wall time in nanoseconds
|
||||
[[nodiscard]] virtual std::chrono::nanoseconds GetTimeNS() = 0;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace Common {
|
||||
|
||||
namespace X64 {
|
||||
class NativeClock final : public WallClock {
|
||||
class NativeClock : public WallClock {
|
||||
public:
|
||||
NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency);
|
||||
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ public:
|
||||
* Gets the instance of the System singleton class.
|
||||
* @returns Reference to the instance of the System singleton class.
|
||||
*/
|
||||
[[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance() {
|
||||
static System& GetInstance() {
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/frontend/applets/controller.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
@@ -13,9 +14,6 @@ namespace Core::Frontend {
|
||||
|
||||
ControllerApplet::~ControllerApplet() = default;
|
||||
|
||||
DefaultControllerApplet::DefaultControllerApplet(Service::SM::ServiceManager& service_manager_)
|
||||
: service_manager{service_manager_} {}
|
||||
|
||||
DefaultControllerApplet::~DefaultControllerApplet() = default;
|
||||
|
||||
void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback,
|
||||
@@ -23,7 +21,9 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
|
||||
LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!");
|
||||
|
||||
auto& npad =
|
||||
service_manager.GetService<Service::HID::Hid>("hid")
|
||||
Core::System::GetInstance()
|
||||
.ServiceManager()
|
||||
.GetService<Service::HID::Hid>("hid")
|
||||
->GetAppletResource()
|
||||
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad);
|
||||
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Service::SM {
|
||||
class ServiceManager;
|
||||
}
|
||||
|
||||
namespace Core::Frontend {
|
||||
|
||||
using BorderColor = std::array<u8, 4>;
|
||||
@@ -43,14 +39,10 @@ public:
|
||||
|
||||
class DefaultControllerApplet final : public ControllerApplet {
|
||||
public:
|
||||
explicit DefaultControllerApplet(Service::SM::ServiceManager& service_manager_);
|
||||
~DefaultControllerApplet() override;
|
||||
|
||||
void ReconfigureControllers(std::function<void()> callback,
|
||||
ControllerParameters parameters) const override;
|
||||
|
||||
private:
|
||||
Service::SM::ServiceManager& service_manager;
|
||||
};
|
||||
|
||||
} // namespace Core::Frontend
|
||||
@@ -33,9 +33,6 @@ public:
|
||||
virtual bool GetAnalogDirectionStatus(AnalogDirection direction) const {
|
||||
return {};
|
||||
}
|
||||
virtual bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
/// An abstract class template for a factory that can create input devices.
|
||||
|
||||
@@ -774,17 +774,6 @@ void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Module::Interface::LoadOpenContext(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
|
||||
// This is similar to GetBaasAccountManagerForApplication
|
||||
// This command is used concurrently with ListOpenContextStoredUsers
|
||||
// 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());
|
||||
}
|
||||
|
||||
void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ public:
|
||||
void IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx);
|
||||
void GetProfileEditor(Kernel::HLERequestContext& ctx);
|
||||
void ListQualifiedUsers(Kernel::HLERequestContext& ctx);
|
||||
void LoadOpenContext(Kernel::HLERequestContext& ctx);
|
||||
void ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx);
|
||||
|
||||
private:
|
||||
|
||||
@@ -29,7 +29,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
|
||||
{110, nullptr, "StoreSaveDataThumbnail"},
|
||||
{111, nullptr, "ClearSaveDataThumbnail"},
|
||||
{120, nullptr, "CreateGuestLoginRequest"},
|
||||
{130, &ACC_U0::LoadOpenContext, "LoadOpenContext"}, // 5.0.0+
|
||||
{130, nullptr, "LoadOpenContext"}, // 5.0.0+
|
||||
{131, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 6.0.0+
|
||||
{140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"}, // 6.0.0+
|
||||
{141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
|
||||
|
||||
@@ -206,8 +206,7 @@ void AppletManager::SetDefaultAppletFrontendSet() {
|
||||
|
||||
void AppletManager::SetDefaultAppletsIfMissing() {
|
||||
if (frontend.controller == nullptr) {
|
||||
frontend.controller =
|
||||
std::make_unique<Core::Frontend::DefaultControllerApplet>(system.ServiceManager());
|
||||
frontend.controller = std::make_unique<Core::Frontend::DefaultControllerApplet>();
|
||||
}
|
||||
|
||||
if (frontend.e_commerce == nullptr) {
|
||||
|
||||
@@ -31,10 +31,6 @@ public:
|
||||
virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) = 0;
|
||||
|
||||
// When the controller is requesting a motion update for the shared memory
|
||||
virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) {}
|
||||
|
||||
// Called when input devices should be loaded
|
||||
virtual void OnLoadInputDevices() = 0;
|
||||
|
||||
|
||||
@@ -365,6 +365,44 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
}
|
||||
const u32 npad_index = static_cast<u32>(i);
|
||||
|
||||
const std::array<SixAxisGeneric*, 6> controller_sixaxes{
|
||||
&npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
|
||||
&npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right,
|
||||
};
|
||||
|
||||
for (auto* sixaxis_sensor : controller_sixaxes) {
|
||||
sixaxis_sensor->common.entry_count = 16;
|
||||
sixaxis_sensor->common.total_entry_count = 17;
|
||||
|
||||
const auto& last_entry =
|
||||
sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
|
||||
|
||||
sixaxis_sensor->common.timestamp = core_timing.GetCPUTicks();
|
||||
sixaxis_sensor->common.last_entry_index =
|
||||
(sixaxis_sensor->common.last_entry_index + 1) % 17;
|
||||
|
||||
auto& cur_entry = sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
|
||||
|
||||
cur_entry.timestamp = last_entry.timestamp + 1;
|
||||
cur_entry.timestamp2 = cur_entry.timestamp;
|
||||
}
|
||||
|
||||
// Try to read sixaxis sensor states
|
||||
std::array<MotionDevice, 2> motion_devices;
|
||||
|
||||
if (sixaxis_sensors_enabled && Settings::values.motion_enabled) {
|
||||
sixaxis_at_rest = true;
|
||||
for (std::size_t e = 0; e < motion_devices.size(); ++e) {
|
||||
const auto& device = motions[i][e];
|
||||
if (device) {
|
||||
std::tie(motion_devices[e].accel, motion_devices[e].gyro,
|
||||
motion_devices[e].rotation, motion_devices[e].orientation) =
|
||||
device->GetStatus();
|
||||
sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.0001f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RequestPadStateUpdate(npad_index);
|
||||
auto& pad_state = npad_pad_states[npad_index];
|
||||
|
||||
@@ -408,6 +446,13 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
main_controller.pad.r_stick = pad_state.r_stick;
|
||||
|
||||
libnx_entry.connection_status.IsWired.Assign(1);
|
||||
|
||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||
full_sixaxis_entry.accel = motion_devices[0].accel;
|
||||
full_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||
full_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||
full_sixaxis_entry.orientation = motion_devices[0].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::Handheld:
|
||||
handheld_entry.connection_status.raw = 0;
|
||||
@@ -426,6 +471,13 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
|
||||
libnx_entry.connection_status.IsLeftJoyWired.Assign(1);
|
||||
libnx_entry.connection_status.IsRightJoyWired.Assign(1);
|
||||
|
||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||
handheld_sixaxis_entry.accel = motion_devices[0].accel;
|
||||
handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||
handheld_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||
handheld_sixaxis_entry.orientation = motion_devices[0].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::JoyDual:
|
||||
dual_entry.connection_status.raw = 0;
|
||||
@@ -438,6 +490,21 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
|
||||
libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
||||
libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
|
||||
|
||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||
// Set motion for the left joycon
|
||||
dual_left_sixaxis_entry.accel = motion_devices[0].accel;
|
||||
dual_left_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||
dual_left_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||
dual_left_sixaxis_entry.orientation = motion_devices[0].orientation;
|
||||
}
|
||||
if (sixaxis_sensors_enabled && motions[i][1]) {
|
||||
// Set motion for the right joycon
|
||||
dual_right_sixaxis_entry.accel = motion_devices[1].accel;
|
||||
dual_right_sixaxis_entry.gyro = motion_devices[1].gyro;
|
||||
dual_right_sixaxis_entry.rotation = motion_devices[1].rotation;
|
||||
dual_right_sixaxis_entry.orientation = motion_devices[1].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::JoyLeft:
|
||||
left_entry.connection_status.raw = 0;
|
||||
@@ -448,6 +515,13 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
left_entry.pad.r_stick = pad_state.r_stick;
|
||||
|
||||
libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
|
||||
|
||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||
left_sixaxis_entry.accel = motion_devices[0].accel;
|
||||
left_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||
left_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||
left_sixaxis_entry.orientation = motion_devices[0].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::JoyRight:
|
||||
right_entry.connection_status.raw = 0;
|
||||
@@ -458,6 +532,13 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
right_entry.pad.r_stick = pad_state.r_stick;
|
||||
|
||||
libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
|
||||
|
||||
if (sixaxis_sensors_enabled && motions[i][1]) {
|
||||
right_sixaxis_entry.accel = motion_devices[1].accel;
|
||||
right_sixaxis_entry.gyro = motion_devices[1].gyro;
|
||||
right_sixaxis_entry.rotation = motion_devices[1].rotation;
|
||||
right_sixaxis_entry.orientation = motion_devices[1].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::Pokeball:
|
||||
pokeball_entry.connection_status.raw = 0;
|
||||
@@ -480,143 +561,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
|
||||
shared_memory_entries.size() * sizeof(NPadEntry));
|
||||
}
|
||||
|
||||
void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t data_len) {
|
||||
if (!IsControllerActivated()) {
|
||||
return;
|
||||
}
|
||||
for (std::size_t i = 0; i < shared_memory_entries.size(); i++) {
|
||||
auto& npad = shared_memory_entries[i];
|
||||
|
||||
const auto& controller_type = connected_controllers[i].type;
|
||||
|
||||
if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::array<SixAxisGeneric*, 6> controller_sixaxes{
|
||||
&npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
|
||||
&npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right,
|
||||
};
|
||||
|
||||
for (auto* sixaxis_sensor : controller_sixaxes) {
|
||||
sixaxis_sensor->common.entry_count = 16;
|
||||
sixaxis_sensor->common.total_entry_count = 17;
|
||||
|
||||
const auto& last_entry =
|
||||
sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
|
||||
|
||||
sixaxis_sensor->common.timestamp = core_timing.GetCPUTicks();
|
||||
sixaxis_sensor->common.last_entry_index =
|
||||
(sixaxis_sensor->common.last_entry_index + 1) % 17;
|
||||
|
||||
auto& cur_entry = sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
|
||||
|
||||
cur_entry.timestamp = last_entry.timestamp + 1;
|
||||
cur_entry.timestamp2 = cur_entry.timestamp;
|
||||
}
|
||||
|
||||
// Try to read sixaxis sensor states
|
||||
std::array<MotionDevice, 2> motion_devices;
|
||||
|
||||
if (sixaxis_sensors_enabled && Settings::values.motion_enabled) {
|
||||
sixaxis_at_rest = true;
|
||||
for (std::size_t e = 0; e < motion_devices.size(); ++e) {
|
||||
const auto& device = motions[i][e];
|
||||
if (device) {
|
||||
std::tie(motion_devices[e].accel, motion_devices[e].gyro,
|
||||
motion_devices[e].rotation, motion_devices[e].orientation) =
|
||||
device->GetStatus();
|
||||
sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.0001f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto& main_controller =
|
||||
npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index];
|
||||
auto& handheld_entry =
|
||||
npad.handheld_states.npad[npad.handheld_states.common.last_entry_index];
|
||||
auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index];
|
||||
auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index];
|
||||
auto& right_entry =
|
||||
npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index];
|
||||
auto& pokeball_entry =
|
||||
npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index];
|
||||
auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
|
||||
|
||||
auto& full_sixaxis_entry =
|
||||
npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
|
||||
auto& handheld_sixaxis_entry =
|
||||
npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
|
||||
auto& dual_left_sixaxis_entry =
|
||||
npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index];
|
||||
auto& dual_right_sixaxis_entry =
|
||||
npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index];
|
||||
auto& left_sixaxis_entry =
|
||||
npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index];
|
||||
auto& right_sixaxis_entry =
|
||||
npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index];
|
||||
|
||||
switch (controller_type) {
|
||||
case NPadControllerType::None:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case NPadControllerType::ProController:
|
||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||
full_sixaxis_entry.accel = motion_devices[0].accel;
|
||||
full_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||
full_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||
full_sixaxis_entry.orientation = motion_devices[0].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::Handheld:
|
||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||
handheld_sixaxis_entry.accel = motion_devices[0].accel;
|
||||
handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||
handheld_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||
handheld_sixaxis_entry.orientation = motion_devices[0].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::JoyDual:
|
||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||
// Set motion for the left joycon
|
||||
dual_left_sixaxis_entry.accel = motion_devices[0].accel;
|
||||
dual_left_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||
dual_left_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||
dual_left_sixaxis_entry.orientation = motion_devices[0].orientation;
|
||||
}
|
||||
if (sixaxis_sensors_enabled && motions[i][1]) {
|
||||
// Set motion for the right joycon
|
||||
dual_right_sixaxis_entry.accel = motion_devices[1].accel;
|
||||
dual_right_sixaxis_entry.gyro = motion_devices[1].gyro;
|
||||
dual_right_sixaxis_entry.rotation = motion_devices[1].rotation;
|
||||
dual_right_sixaxis_entry.orientation = motion_devices[1].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::JoyLeft:
|
||||
if (sixaxis_sensors_enabled && motions[i][0]) {
|
||||
left_sixaxis_entry.accel = motion_devices[0].accel;
|
||||
left_sixaxis_entry.gyro = motion_devices[0].gyro;
|
||||
left_sixaxis_entry.rotation = motion_devices[0].rotation;
|
||||
left_sixaxis_entry.orientation = motion_devices[0].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::JoyRight:
|
||||
if (sixaxis_sensors_enabled && motions[i][1]) {
|
||||
right_sixaxis_entry.accel = motion_devices[1].accel;
|
||||
right_sixaxis_entry.gyro = motion_devices[1].gyro;
|
||||
right_sixaxis_entry.rotation = motion_devices[1].rotation;
|
||||
right_sixaxis_entry.orientation = motion_devices[1].orientation;
|
||||
}
|
||||
break;
|
||||
case NPadControllerType::Pokeball:
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
|
||||
shared_memory_entries.size() * sizeof(NPadEntry));
|
||||
}
|
||||
|
||||
void Controller_NPad::SetSupportedStyleSet(NPadType style_set) {
|
||||
style.raw = style_set.raw;
|
||||
}
|
||||
@@ -665,31 +609,20 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode)
|
||||
}
|
||||
}
|
||||
|
||||
void Controller_NPad::VibrateController(const std::vector<u32>& controllers,
|
||||
void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
|
||||
const std::vector<Vibration>& vibrations) {
|
||||
LOG_TRACE(Service_HID, "called");
|
||||
LOG_DEBUG(Service_HID, "(STUBBED) called");
|
||||
|
||||
if (!Settings::values.vibration_enabled || !can_controllers_vibrate) {
|
||||
return;
|
||||
}
|
||||
bool success = true;
|
||||
for (std::size_t i = 0; i < controllers.size(); ++i) {
|
||||
if (!connected_controllers[i].is_connected) {
|
||||
continue;
|
||||
}
|
||||
using namespace Settings::NativeButton;
|
||||
const auto& button_state = buttons[i];
|
||||
if (button_state[A - BUTTON_HID_BEGIN]) {
|
||||
if (button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
|
||||
vibrations[0].amp_high, vibrations[0].amp_low, vibrations[0].freq_high,
|
||||
vibrations[0].freq_low)) {
|
||||
success = false;
|
||||
}
|
||||
for (std::size_t i = 0; i < controller_ids.size(); i++) {
|
||||
std::size_t controller_pos = NPadIdToIndex(static_cast<u32>(i));
|
||||
if (connected_controllers[controller_pos].is_connected) {
|
||||
// TODO(ogniK): Vibrate the physical controller
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
last_processed_vibration = vibrations.back();
|
||||
}
|
||||
last_processed_vibration = vibrations.back();
|
||||
}
|
||||
|
||||
Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
|
||||
|
||||
@@ -32,10 +32,6 @@ public:
|
||||
// When the controller is requesting an update for the shared memory
|
||||
void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
|
||||
|
||||
// When the controller is requesting a motion update for the shared memory
|
||||
void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) override;
|
||||
|
||||
// Called when input devices should be loaded
|
||||
void OnLoadInputDevices() override;
|
||||
|
||||
@@ -125,7 +121,7 @@ public:
|
||||
|
||||
void SetNpadMode(u32 npad_id, NPadAssignments assignment_mode);
|
||||
|
||||
void VibrateController(const std::vector<u32>& controllers,
|
||||
void VibrateController(const std::vector<u32>& controller_ids,
|
||||
const std::vector<Vibration>& vibrations);
|
||||
|
||||
Vibration GetLastVibration() const;
|
||||
|
||||
@@ -40,8 +40,7 @@ namespace Service::HID {
|
||||
// Updating period for each HID device.
|
||||
// HID is polled every 15ms, this value was derived from
|
||||
// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet
|
||||
constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz)
|
||||
constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz)
|
||||
constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz)
|
||||
constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
|
||||
|
||||
IAppletResource::IAppletResource(Core::System& system)
|
||||
@@ -80,14 +79,10 @@ IAppletResource::IAppletResource(Core::System& system)
|
||||
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
|
||||
UpdateControllers(user_data, ns_late);
|
||||
});
|
||||
motion_update_event = Core::Timing::CreateEvent(
|
||||
"HID::MotionPadCallback",
|
||||
[this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
|
||||
UpdateMotion(user_data, ns_late);
|
||||
});
|
||||
|
||||
// TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
|
||||
|
||||
system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event);
|
||||
system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event);
|
||||
|
||||
ReloadInputDevices();
|
||||
}
|
||||
@@ -127,16 +122,6 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
|
||||
core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event);
|
||||
}
|
||||
|
||||
void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
|
||||
auto& core_timing = system.CoreTiming();
|
||||
|
||||
for (const auto& controller : controllers) {
|
||||
controller->OnMotionUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
|
||||
}
|
||||
|
||||
core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event);
|
||||
}
|
||||
|
||||
class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
|
||||
public:
|
||||
IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
|
||||
@@ -188,7 +173,7 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
|
||||
{66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
|
||||
{67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"},
|
||||
{68, nullptr, "IsSixAxisSensorFusionEnabled"},
|
||||
{69, &Hid::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"},
|
||||
{69, nullptr, "EnableSixAxisSensorFusion"},
|
||||
{70, nullptr, "SetSixAxisSensorFusionParameters"},
|
||||
{71, nullptr, "GetSixAxisSensorFusionParameters"},
|
||||
{72, nullptr, "ResetSixAxisSensorFusionParameters"},
|
||||
@@ -473,19 +458,6 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto enable{rp.Pop<bool>()};
|
||||
const auto handle{rp.Pop<u32>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
|
||||
applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto handle{rp.Pop<u32>()};
|
||||
@@ -830,18 +802,18 @@ void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto controller{rp.Pop<u32>()};
|
||||
const auto controller_id{rp.Pop<u32>()};
|
||||
const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_HID, "called, controller={}, applet_resource_user_id={}", controller,
|
||||
LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
|
||||
applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||
.VibrateController({controller}, {vibration_values});
|
||||
.VibrateController({controller_id}, {vibration_values});
|
||||
}
|
||||
|
||||
void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
|
||||
@@ -859,6 +831,8 @@ void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
std::memcpy(controller_list.data(), controllers.data(), controllers.size());
|
||||
std::memcpy(vibration_list.data(), vibrations.data(), vibrations.size());
|
||||
std::transform(controller_list.begin(), controller_list.end(), controller_list.begin(),
|
||||
[](u32 controller_id) { return controller_id - 3; });
|
||||
|
||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||
.VibrateController(controller_list, vibration_list);
|
||||
|
||||
@@ -65,12 +65,10 @@ private:
|
||||
|
||||
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
|
||||
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
|
||||
void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
|
||||
|
||||
std::shared_ptr<Kernel::SharedMemory> shared_mem;
|
||||
|
||||
std::shared_ptr<Core::Timing::EventType> pad_update_event;
|
||||
std::shared_ptr<Core::Timing::EventType> motion_update_event;
|
||||
Core::System& system;
|
||||
|
||||
std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
|
||||
@@ -99,7 +97,6 @@ private:
|
||||
void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx);
|
||||
void StartSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx);
|
||||
void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
|
||||
void GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
|
||||
void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
|
||||
|
||||
@@ -72,23 +72,6 @@
|
||||
|
||||
namespace Service {
|
||||
|
||||
/**
|
||||
* Creates a function string for logging, complete with the name (or header code, depending
|
||||
* on what's passed in) the port name, and all the cmd_buff arguments.
|
||||
*/
|
||||
[[maybe_unused]] static std::string MakeFunctionString(std::string_view name,
|
||||
std::string_view port_name,
|
||||
const u32* cmd_buff) {
|
||||
// Number of params == bits 0-5 + bits 6-11
|
||||
int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F);
|
||||
|
||||
std::string function_string = fmt::format("function '{}': port={}", name, port_name);
|
||||
for (int i = 1; i <= num_params; ++i) {
|
||||
function_string += fmt::format(", cmd_buff[{}]=0x{:X}", i, cmd_buff[i]);
|
||||
}
|
||||
return function_string;
|
||||
}
|
||||
|
||||
ServiceFrameworkBase::ServiceFrameworkBase(const char* service_name, u32 max_sessions,
|
||||
InvokerFn* handler_invoker)
|
||||
: service_name(service_name), max_sessions(max_sessions), handler_invoker(handler_invoker) {}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
@@ -79,33 +78,6 @@ public:
|
||||
return state.axes.at(axis) / (32767.0f * range);
|
||||
}
|
||||
|
||||
bool RumblePlay(f32 amp_low, f32 amp_high, int time) {
|
||||
const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF);
|
||||
const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF);
|
||||
// Lower drastically the number of state changes
|
||||
if (raw_amp_low >> 11 == last_state_rumble_low >> 11 &&
|
||||
raw_amp_high >> 11 == last_state_rumble_high >> 11) {
|
||||
if (raw_amp_low + raw_amp_high != 0 ||
|
||||
last_state_rumble_low + last_state_rumble_high == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Don't change state if last vibration was < 20ms
|
||||
const auto now = std::chrono::system_clock::now();
|
||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_vibration) <
|
||||
std::chrono::milliseconds(20)) {
|
||||
return raw_amp_low + raw_amp_high == 0;
|
||||
}
|
||||
|
||||
last_vibration = now;
|
||||
last_state_rumble_low = raw_amp_low;
|
||||
last_state_rumble_high = raw_amp_high;
|
||||
if (sdl_joystick) {
|
||||
SDL_JoystickRumble(sdl_joystick.get(), raw_amp_low, raw_amp_high, time);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::tuple<float, float> GetAnalog(int axis_x, int axis_y, float range) const {
|
||||
float x = GetAxis(axis_x, range);
|
||||
float y = GetAxis(axis_y, range);
|
||||
@@ -167,9 +139,6 @@ private:
|
||||
} state;
|
||||
std::string guid;
|
||||
int port;
|
||||
u16 last_state_rumble_high;
|
||||
u16 last_state_rumble_low;
|
||||
std::chrono::time_point<std::chrono::system_clock> last_vibration;
|
||||
std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick;
|
||||
std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller;
|
||||
mutable std::mutex mutex;
|
||||
@@ -238,7 +207,7 @@ void SDLState::InitJoystick(int joystick_index) {
|
||||
sdl_gamecontroller = SDL_GameControllerOpen(joystick_index);
|
||||
}
|
||||
if (!sdl_joystick) {
|
||||
LOG_ERROR(Input, "Failed to open joystick {}", joystick_index);
|
||||
LOG_ERROR(Input, "failed to open joystick {}", joystick_index);
|
||||
return;
|
||||
}
|
||||
const std::string guid = GetGUID(sdl_joystick);
|
||||
@@ -334,12 +303,6 @@ public:
|
||||
return joystick->GetButton(button);
|
||||
}
|
||||
|
||||
bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override {
|
||||
const f32 new_amp_low = pow(amp_low, 0.5f) * (3.0f - 2.0f * pow(amp_low, 0.15f));
|
||||
const f32 new_amp_high = pow(amp_high, 0.5f) * (3.0f - 2.0f * pow(amp_high, 0.15f));
|
||||
return joystick->RumblePlay(new_amp_low, new_amp_high, 250);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<SDLJoystick> joystick;
|
||||
int button;
|
||||
|
||||
@@ -12,11 +12,6 @@ namespace Vulkan {
|
||||
|
||||
constexpr size_t COMMAND_BUFFER_POOL_SIZE = 0x1000;
|
||||
|
||||
struct CommandPool::Pool {
|
||||
vk::CommandPool handle;
|
||||
vk::CommandBuffers cmdbufs;
|
||||
};
|
||||
|
||||
CommandPool::CommandPool(MasterSemaphore& master_semaphore, const VKDevice& device)
|
||||
: ResourcePool(master_semaphore, COMMAND_BUFFER_POOL_SIZE), device{device} {}
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
@@ -18,14 +16,17 @@ class VKDevice;
|
||||
class CommandPool final : public ResourcePool {
|
||||
public:
|
||||
explicit CommandPool(MasterSemaphore& master_semaphore, const VKDevice& device);
|
||||
~CommandPool() override;
|
||||
virtual ~CommandPool();
|
||||
|
||||
void Allocate(size_t begin, size_t end) override;
|
||||
|
||||
VkCommandBuffer Commit();
|
||||
|
||||
private:
|
||||
struct Pool;
|
||||
struct Pool {
|
||||
vk::CommandPool handle;
|
||||
vk::CommandBuffers cmdbufs;
|
||||
};
|
||||
|
||||
const VKDevice& device;
|
||||
std::vector<Pool> pools;
|
||||
|
||||
@@ -388,6 +388,14 @@ bool VKDevice::Create() {
|
||||
|
||||
CollectTelemetryParameters();
|
||||
|
||||
if (ext_extended_dynamic_state && driver_id == VK_DRIVER_ID_AMD_PROPRIETARY_KHR) {
|
||||
// AMD's proprietary driver supports VK_EXT_extended_dynamic_state but the <stride> field
|
||||
// seems to be bugged. Blacklisting it for now.
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Blacklisting AMD proprietary from VK_EXT_extended_dynamic_state");
|
||||
ext_extended_dynamic_state = false;
|
||||
}
|
||||
|
||||
graphics_queue = logical.GetQueue(graphics_family);
|
||||
present_queue = logical.GetQueue(present_family);
|
||||
|
||||
|
||||
@@ -120,8 +120,7 @@ void VKStreamBuffer::CreateBuffers(VkBufferUsageFlags usage) {
|
||||
|
||||
// Substract from the preferred heap size some bytes to avoid getting out of memory.
|
||||
const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size;
|
||||
// As per DXVK's example, using `heap_size / 2`
|
||||
const VkDeviceSize allocable_size = heap_size / 2;
|
||||
const VkDeviceSize allocable_size = heap_size - 9 * 1024 * 1024;
|
||||
buffer = device.GetLogical().CreateBuffer({
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
|
||||
@@ -28,26 +28,23 @@ u32 ShaderIR::DecodeArithmeticIntegerImmediate(NodeBlock& bb, u32 pc) {
|
||||
case OpCode::Id::IADD32I: {
|
||||
UNIMPLEMENTED_IF_MSG(instr.iadd32i.saturate, "IADD32I saturation is not implemented");
|
||||
|
||||
op_a = GetOperandAbsNegInteger(std::move(op_a), false, instr.iadd32i.negate_a != 0, true);
|
||||
op_a = GetOperandAbsNegInteger(op_a, false, instr.iadd32i.negate_a, true);
|
||||
|
||||
Node value = Operation(OperationCode::IAdd, PRECISE, std::move(op_a), std::move(op_b));
|
||||
const Node value = Operation(OperationCode::IAdd, PRECISE, op_a, op_b);
|
||||
|
||||
SetInternalFlagsFromInteger(bb, value, instr.op_32.generates_cc != 0);
|
||||
SetRegister(bb, instr.gpr0, std::move(value));
|
||||
SetInternalFlagsFromInteger(bb, value, instr.op_32.generates_cc);
|
||||
SetRegister(bb, instr.gpr0, value);
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::LOP32I: {
|
||||
if (instr.alu.lop32i.invert_a) {
|
||||
op_a = Operation(OperationCode::IBitwiseNot, NO_PRECISE, std::move(op_a));
|
||||
}
|
||||
if (instr.alu.lop32i.invert_a)
|
||||
op_a = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_a);
|
||||
|
||||
if (instr.alu.lop32i.invert_b) {
|
||||
op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, std::move(op_b));
|
||||
}
|
||||
if (instr.alu.lop32i.invert_b)
|
||||
op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_b);
|
||||
|
||||
WriteLogicOperation(bb, instr.gpr0, instr.alu.lop32i.operation, std::move(op_a),
|
||||
std::move(op_b), PredicateResultMode::None, Pred::UnusedIndex,
|
||||
instr.op_32.generates_cc != 0);
|
||||
WriteLogicOperation(bb, instr.gpr0, instr.alu.lop32i.operation, op_a, op_b,
|
||||
PredicateResultMode::None, Pred::UnusedIndex, instr.op_32.generates_cc);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -61,14 +58,14 @@ u32 ShaderIR::DecodeArithmeticIntegerImmediate(NodeBlock& bb, u32 pc) {
|
||||
void ShaderIR::WriteLogicOperation(NodeBlock& bb, Register dest, LogicOperation logic_op, Node op_a,
|
||||
Node op_b, PredicateResultMode predicate_mode, Pred predicate,
|
||||
bool sets_cc) {
|
||||
Node result = [&] {
|
||||
const Node result = [&]() {
|
||||
switch (logic_op) {
|
||||
case LogicOperation::And:
|
||||
return Operation(OperationCode::IBitwiseAnd, PRECISE, std::move(op_a), std::move(op_b));
|
||||
return Operation(OperationCode::IBitwiseAnd, PRECISE, op_a, op_b);
|
||||
case LogicOperation::Or:
|
||||
return Operation(OperationCode::IBitwiseOr, PRECISE, std::move(op_a), std::move(op_b));
|
||||
return Operation(OperationCode::IBitwiseOr, PRECISE, op_a, op_b);
|
||||
case LogicOperation::Xor:
|
||||
return Operation(OperationCode::IBitwiseXor, PRECISE, std::move(op_a), std::move(op_b));
|
||||
return Operation(OperationCode::IBitwiseXor, PRECISE, op_a, op_b);
|
||||
case LogicOperation::PassB:
|
||||
return op_b;
|
||||
default:
|
||||
@@ -87,8 +84,8 @@ void ShaderIR::WriteLogicOperation(NodeBlock& bb, Register dest, LogicOperation
|
||||
return;
|
||||
case PredicateResultMode::NotZero: {
|
||||
// Set the predicate to true if the result is not zero.
|
||||
Node compare = Operation(OperationCode::LogicalINotEqual, std::move(result), Immediate(0));
|
||||
SetPredicate(bb, static_cast<u64>(predicate), std::move(compare));
|
||||
const Node compare = Operation(OperationCode::LogicalINotEqual, result, Immediate(0));
|
||||
SetPredicate(bb, static_cast<u64>(predicate), compare);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -24,45 +24,44 @@ GraphicsInfo MakeGraphicsInfo(ShaderType shader_stage, ConstBufferEngineInterfac
|
||||
if (shader_stage == ShaderType::Compute) {
|
||||
return {};
|
||||
}
|
||||
auto& graphics = static_cast<Tegra::Engines::Maxwell3D&>(engine);
|
||||
|
||||
auto& graphics = dynamic_cast<Tegra::Engines::Maxwell3D&>(engine);
|
||||
|
||||
return {
|
||||
.tfb_layouts = graphics.regs.tfb_layouts,
|
||||
.tfb_varying_locs = graphics.regs.tfb_varying_locs,
|
||||
.primitive_topology = graphics.regs.draw.topology,
|
||||
.tessellation_primitive = graphics.regs.tess_mode.prim,
|
||||
.tessellation_spacing = graphics.regs.tess_mode.spacing,
|
||||
.tfb_enabled = graphics.regs.tfb_enabled != 0,
|
||||
.tessellation_clockwise = graphics.regs.tess_mode.cw.Value() != 0,
|
||||
};
|
||||
GraphicsInfo info;
|
||||
info.tfb_layouts = graphics.regs.tfb_layouts;
|
||||
info.tfb_varying_locs = graphics.regs.tfb_varying_locs;
|
||||
info.primitive_topology = graphics.regs.draw.topology;
|
||||
info.tessellation_primitive = graphics.regs.tess_mode.prim;
|
||||
info.tessellation_spacing = graphics.regs.tess_mode.spacing;
|
||||
info.tfb_enabled = graphics.regs.tfb_enabled;
|
||||
info.tessellation_clockwise = graphics.regs.tess_mode.cw;
|
||||
return info;
|
||||
}
|
||||
|
||||
ComputeInfo MakeComputeInfo(ShaderType shader_stage, ConstBufferEngineInterface& engine) {
|
||||
if (shader_stage != ShaderType::Compute) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto& compute = dynamic_cast<Tegra::Engines::KeplerCompute&>(engine);
|
||||
auto& compute = static_cast<Tegra::Engines::KeplerCompute&>(engine);
|
||||
const auto& launch = compute.launch_description;
|
||||
|
||||
return {
|
||||
.workgroup_size = {launch.block_dim_x, launch.block_dim_y, launch.block_dim_z},
|
||||
.shared_memory_size_in_words = launch.shared_alloc,
|
||||
.local_memory_size_in_words = launch.local_pos_alloc,
|
||||
};
|
||||
ComputeInfo info;
|
||||
info.workgroup_size = {launch.block_dim_x, launch.block_dim_y, launch.block_dim_z};
|
||||
info.local_memory_size_in_words = launch.local_pos_alloc;
|
||||
info.shared_memory_size_in_words = launch.shared_alloc;
|
||||
return info;
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
Registry::Registry(ShaderType shader_stage, const SerializedRegistryInfo& info)
|
||||
Registry::Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info)
|
||||
: stage{shader_stage}, stored_guest_driver_profile{info.guest_driver_profile},
|
||||
bound_buffer{info.bound_buffer}, graphics_info{info.graphics}, compute_info{info.compute} {}
|
||||
|
||||
Registry::Registry(ShaderType shader_stage, ConstBufferEngineInterface& engine_)
|
||||
: stage{shader_stage}, engine{&engine_}, bound_buffer{engine_.GetBoundBuffer()},
|
||||
graphics_info{MakeGraphicsInfo(shader_stage, engine_)}, compute_info{MakeComputeInfo(
|
||||
shader_stage, engine_)} {}
|
||||
Registry::Registry(Tegra::Engines::ShaderType shader_stage,
|
||||
Tegra::Engines::ConstBufferEngineInterface& engine)
|
||||
: stage{shader_stage}, engine{&engine}, bound_buffer{engine.GetBoundBuffer()},
|
||||
graphics_info{MakeGraphicsInfo(shader_stage, engine)}, compute_info{MakeComputeInfo(
|
||||
shader_stage, engine)} {}
|
||||
|
||||
Registry::~Registry() = default;
|
||||
|
||||
@@ -114,7 +113,8 @@ std::optional<Tegra::Engines::SamplerDescriptor> Registry::ObtainSeparateSampler
|
||||
return value;
|
||||
}
|
||||
|
||||
std::optional<SamplerDescriptor> Registry::ObtainBindlessSampler(u32 buffer, u32 offset) {
|
||||
std::optional<Tegra::Engines::SamplerDescriptor> Registry::ObtainBindlessSampler(u32 buffer,
|
||||
u32 offset) {
|
||||
const std::pair key = {buffer, offset};
|
||||
const auto iter = bindless_samplers.find(key);
|
||||
if (iter != bindless_samplers.end()) {
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
explicit Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info);
|
||||
|
||||
explicit Registry(Tegra::Engines::ShaderType shader_stage,
|
||||
Tegra::Engines::ConstBufferEngineInterface& engine_);
|
||||
Tegra::Engines::ConstBufferEngineInterface& engine);
|
||||
|
||||
~Registry();
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
#include "yuzu/main.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
|
||||
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent)
|
||||
: QObject(parent), gamelist{gamelist} {}
|
||||
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) : gamelist{gamelist} {}
|
||||
|
||||
// EventFilter in order to process systemkeys while editing the searchfield
|
||||
bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) {
|
||||
@@ -117,7 +116,7 @@ void GameListSearchField::setFocus() {
|
||||
}
|
||||
|
||||
GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
|
||||
auto* const key_release_eater = new KeyReleaseEater(parent, this);
|
||||
auto* const key_release_eater = new KeyReleaseEater(parent);
|
||||
layout_filter = new QHBoxLayout;
|
||||
layout_filter->setMargin(8);
|
||||
label_filter = new QLabel;
|
||||
|
||||
@@ -330,7 +330,7 @@ public:
|
||||
private:
|
||||
class KeyReleaseEater : public QObject {
|
||||
public:
|
||||
explicit KeyReleaseEater(GameList* gamelist, QObject* parent = nullptr);
|
||||
explicit KeyReleaseEater(GameList* gamelist);
|
||||
|
||||
private:
|
||||
GameList* gamelist = nullptr;
|
||||
|
||||
+6
-8
@@ -288,8 +288,8 @@ GMainWindow::~GMainWindow() {
|
||||
void GMainWindow::ControllerSelectorReconfigureControllers(
|
||||
const Core::Frontend::ControllerParameters& parameters) {
|
||||
QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get());
|
||||
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
|
||||
Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
|
||||
Qt::WindowSystemMenuHint);
|
||||
dialog.setWindowModality(Qt::WindowModal);
|
||||
dialog.exec();
|
||||
|
||||
@@ -307,9 +307,8 @@ void GMainWindow::ProfileSelectorSelectProfile() {
|
||||
int index = 0;
|
||||
if (manager.GetUserCount() != 1) {
|
||||
QtProfileSelectionDialog dialog(this);
|
||||
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
|
||||
Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowCloseButtonHint);
|
||||
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
|
||||
Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
|
||||
dialog.setWindowModality(Qt::WindowModal);
|
||||
|
||||
if (dialog.exec() == QDialog::Rejected) {
|
||||
@@ -332,9 +331,8 @@ void GMainWindow::ProfileSelectorSelectProfile() {
|
||||
void GMainWindow::SoftwareKeyboardGetText(
|
||||
const Core::Frontend::SoftwareKeyboardParameters& parameters) {
|
||||
QtSoftwareKeyboardDialog dialog(this, parameters);
|
||||
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
|
||||
Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowCloseButtonHint);
|
||||
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
|
||||
Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
|
||||
dialog.setWindowModality(Qt::WindowModal);
|
||||
|
||||
if (dialog.exec() == QDialog::Rejected) {
|
||||
|
||||
Reference in new issue
Block a user