early-access version 3312

This commit is contained in:
pineappleEA 2023-01-17 06:34:57 +01:00
parent 3405adfe45
commit e2385c7442
105 changed files with 1436 additions and 789 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 3311. This is the source code for early-access 3312.
## Legal Notice ## Legal Notice

BIN
dist/yuzu.ico vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 25 KiB

2
dist/yuzu.svg vendored
View file

@ -1 +1 @@
<svg id="svg815" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 614.4 682.67"><defs><style>.cls-1{fill:none;}.cls-2{clip-path:url(#clip-path);}.cls-3{fill:#ff3c28;}.cls-4{fill:#0ab9e6;}</style><clipPath id="clip-path"><rect class="cls-1" x="-43" y="-46.67" width="699.6" height="777.33"/></clipPath></defs><title>Artboard 1</title><g id="g823"><g id="right"><g class="cls-2"><g id="g827"><g id="g833"><path id="path835" class="cls-3" d="M340.81,138V682.08c150.26,0,272.06-121.81,272.06-272.06S491.07,138,340.81,138M394,197.55a219.06,219.06,0,0,1,0,424.94V197.55"/></g></g></g></g><g id="left"><g class="cls-2"><g id="g839"><g id="g845"><path id="path847" class="cls-4" d="M272.79,1.92C122.53,1.92.73,123.73.73,274s121.8,272.07,272.06,272.07ZM219.65,61.51v425A219,219,0,0,1,118,119.18,217.51,217.51,0,0,1,219.65,61.51"/></g></g></g></g></g></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612.15 680.17"><defs><style>.cls-1{fill:#c6c6c6;}.cls-2{fill:#ffdc00;}</style></defs><title>newAsset 7</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="g823"><g id="right"><g id="g827"><g id="g833"><path id="path835" class="cls-1" d="M340.08,136V680.17c150.26,0,272.07-121.81,272.07-272.07S490.34,136,340.08,136m53.14,59.6a219.06,219.06,0,0,1,0,424.94V195.63"/></g></g></g><g id="left"><g id="g839"><g id="g845"><path id="path847" class="cls-2" d="M272.07,0C121.81,0,0,121.81,0,272.07S121.81,544.13,272.07,544.13ZM218.93,59.6V484.54A219,219,0,0,1,117.26,117.26,217.44,217.44,0,0,1,218.93,59.6"/></g></g></g></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 889 B

After

Width:  |  Height:  |  Size: 717 B

View file

@ -20,25 +20,25 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
const u32 target_sample_count, const u32 source_sample_count, const u32 target_sample_count, const u32 source_sample_count,
UpsamplerState* state) { UpsamplerState* state) {
constexpr u32 WindowSize = 10; constexpr u32 WindowSize = 10;
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow1{ constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc1{
51.93359375f, -18.80078125f, 9.73046875f, -5.33203125f, 2.84375f, 0.95376587f, -0.12872314f, 0.060028076f, -0.032470703f, 0.017669678f,
-1.41015625f, 0.62109375f, -0.2265625f, 0.0625f, -0.00390625f, -0.009124756f, 0.004272461f, -0.001739502f, 0.000579834f, -0.000091552734f,
}; };
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow2{ constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc2{
105.35546875f, -24.52734375f, 11.9609375f, -6.515625f, 3.52734375f, 0.8230896f, -0.19161987f, 0.093444824f, -0.05090332f, 0.027557373f,
-1.796875f, 0.828125f, -0.32421875f, 0.1015625f, -0.015625f, -0.014038086f, 0.0064697266f, -0.002532959f, 0.00079345703f, -0.00012207031f,
}; };
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow3{ constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc3{
122.08203125f, -16.47656250f, 7.68359375f, -4.15625000f, 2.26171875f, 0.6298828f, -0.19274902f, 0.09725952f, -0.05319214f, 0.028625488f,
-1.16796875f, 0.54687500f, -0.22265625f, 0.07421875f, -0.01171875f, -0.014373779f, 0.006500244f, -0.0024719238f, 0.0007324219f, -0.000091552734f,
}; };
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow4{ constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc4{
23.73437500f, -9.62109375f, 5.07812500f, -2.78125000f, 1.46875000f, 0.4057312f, -0.1468811f, 0.07601929f, -0.041656494f, 0.022216797f,
-0.71484375f, 0.30859375f, -0.10546875f, 0.02734375f, 0.00000000f, -0.011016846f, 0.004852295f, -0.0017700195f, 0.00048828125f, -0.000030517578f,
}; };
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow5{ constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc5{
80.62500000f, -24.67187500f, 12.44921875f, -6.80859375f, 3.66406250f, 0.1854248f, -0.075164795f, 0.03967285f, -0.021728516f, 0.011474609f,
-1.83984375f, 0.83203125f, -0.31640625f, 0.09375000f, -0.01171875f, -0.005584717f, 0.0024108887f, -0.0008239746f, 0.00021362305f, 0.0f,
}; };
if (!state->initialized) { if (!state->initialized) {
@ -91,52 +91,31 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
static_cast<u16>((state->history_output_index + 1) % UpsamplerState::HistorySize); static_cast<u16>((state->history_output_index + 1) % UpsamplerState::HistorySize);
}; };
auto calculate_sample = [&state](std::span<const Common::FixedPoint<24, 8>> coeffs1, auto calculate_sample = [&state](std::span<const Common::FixedPoint<17, 15>> coeffs1,
std::span<const Common::FixedPoint<24, 8>> coeffs2) -> s32 { std::span<const Common::FixedPoint<17, 15>> coeffs2) -> s32 {
auto output_index{state->history_output_index}; auto output_index{state->history_output_index};
auto start_pos{output_index - state->history_start_index + 1U}; u64 result{0};
auto end_pos{10U};
if (start_pos < 10) { for (u32 coeff_index = 0; coeff_index < 10; coeff_index++) {
end_pos = start_pos; result += static_cast<u64>(state->history[output_index].to_raw()) *
}
u64 prev_contrib{0};
u32 coeff_index{0};
for (; coeff_index < end_pos; coeff_index++, output_index--) {
prev_contrib += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs1[coeff_index].to_raw(); coeffs1[coeff_index].to_raw();
}
auto end_index{state->history_end_index}; output_index = output_index == state->history_start_index ? state->history_end_index
for (; start_pos < 9; start_pos++, coeff_index++, end_index--) { : output_index - 1;
prev_contrib += static_cast<u64>(state->history[end_index].to_raw()) *
coeffs1[coeff_index].to_raw();
} }
output_index = output_index =
static_cast<u16>((state->history_output_index + 1) % UpsamplerState::HistorySize); static_cast<u16>((state->history_output_index + 1) % UpsamplerState::HistorySize);
start_pos = state->history_end_index - output_index + 1U;
end_pos = 10U;
if (start_pos < 10) { for (u32 coeff_index = 0; coeff_index < 10; coeff_index++) {
end_pos = start_pos; result += static_cast<u64>(state->history[output_index].to_raw()) *
}
u64 next_contrib{0};
coeff_index = 0;
for (; coeff_index < end_pos; coeff_index++, output_index++) {
next_contrib += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs2[coeff_index].to_raw(); coeffs2[coeff_index].to_raw();
output_index = output_index == state->history_end_index ? state->history_start_index
: output_index + 1;
} }
auto start_index{state->history_start_index}; return static_cast<s32>(result >> (8 + 15));
for (; start_pos < 9; start_pos++, start_index++, coeff_index++) {
next_contrib += static_cast<u64>(state->history[start_index].to_raw()) *
coeffs2[coeff_index].to_raw();
}
return static_cast<s32>(((prev_contrib >> 15) + (next_contrib >> 15)) >> 8);
}; };
switch (state->ratio.to_int_floor()) { switch (state->ratio.to_int_floor()) {
@ -150,23 +129,23 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
break; break;
case 1: case 1:
output[write_index] = calculate_sample(SincWindow3, SincWindow4); output[write_index] = calculate_sample(WindowedSinc1, WindowedSinc5);
break; break;
case 2: case 2:
output[write_index] = calculate_sample(SincWindow2, SincWindow1); output[write_index] = calculate_sample(WindowedSinc2, WindowedSinc4);
break; break;
case 3: case 3:
output[write_index] = calculate_sample(SincWindow5, SincWindow5); output[write_index] = calculate_sample(WindowedSinc3, WindowedSinc3);
break; break;
case 4: case 4:
output[write_index] = calculate_sample(SincWindow1, SincWindow2); output[write_index] = calculate_sample(WindowedSinc4, WindowedSinc2);
break; break;
case 5: case 5:
output[write_index] = calculate_sample(SincWindow4, SincWindow3); output[write_index] = calculate_sample(WindowedSinc5, WindowedSinc1);
break; break;
} }
state->sample_index = static_cast<u8>((state->sample_index + 1) % 6); state->sample_index = static_cast<u8>((state->sample_index + 1) % 6);
@ -183,11 +162,11 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
break; break;
case 1: case 1:
output[write_index] = calculate_sample(SincWindow2, SincWindow1); output[write_index] = calculate_sample(WindowedSinc2, WindowedSinc4);
break; break;
case 2: case 2:
output[write_index] = calculate_sample(SincWindow1, SincWindow2); output[write_index] = calculate_sample(WindowedSinc4, WindowedSinc2);
break; break;
} }
state->sample_index = static_cast<u8>((state->sample_index + 1) % 3); state->sample_index = static_cast<u8>((state->sample_index + 1) % 3);
@ -204,12 +183,12 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
break; break;
case 1: case 1:
output[write_index] = calculate_sample(SincWindow1, SincWindow2); output[write_index] = calculate_sample(WindowedSinc4, WindowedSinc2);
break; break;
case 2: case 2:
increment(); increment();
output[write_index] = calculate_sample(SincWindow2, SincWindow1); output[write_index] = calculate_sample(WindowedSinc2, WindowedSinc4);
break; break;
} }
state->sample_index = static_cast<u8>((state->sample_index + 1) % 3); state->sample_index = static_cast<u8>((state->sample_index + 1) % 3);

View file

@ -51,6 +51,8 @@ enum class PollingMode {
NFC, NFC,
// Enable infrared camera polling // Enable infrared camera polling
IR, IR,
// Enable ring controller polling
Ring,
}; };
enum class CameraFormat { enum class CameraFormat {
@ -62,21 +64,22 @@ enum class CameraFormat {
None, None,
}; };
// Vibration reply from the controller // Different results that can happen from a device request
enum class VibrationError { enum class DriverResult {
None, Success,
WrongReply,
Timeout,
UnsupportedControllerType,
HandleInUse,
ErrorReadingData,
ErrorWritingData,
NoDeviceDetected,
InvalidHandle,
NotSupported, NotSupported,
Disabled, Disabled,
Unknown, Unknown,
}; };
// Polling mode reply from the controller
enum class PollingError {
None,
NotSupported,
Unknown,
};
// Nfc reply from the controller // Nfc reply from the controller
enum class NfcState { enum class NfcState {
Success, Success,
@ -90,13 +93,6 @@ enum class NfcState {
Unknown, Unknown,
}; };
// Ir camera reply from the controller
enum class CameraError {
None,
NotSupported,
Unknown,
};
// Hint for amplification curve to be used // Hint for amplification curve to be used
enum class VibrationAmplificationType { enum class VibrationAmplificationType {
Linear, Linear,
@ -190,6 +186,8 @@ struct TouchStatus {
struct BodyColorStatus { struct BodyColorStatus {
u32 body{}; u32 body{};
u32 buttons{}; u32 buttons{};
u32 left_grip{};
u32 right_grip{};
}; };
// HD rumble data // HD rumble data
@ -228,17 +226,31 @@ enum class ButtonNames {
Engine, Engine,
// This will display the button by value instead of the button name // This will display the button by value instead of the button name
Value, Value,
// Joycon button names
ButtonLeft, ButtonLeft,
ButtonRight, ButtonRight,
ButtonDown, ButtonDown,
ButtonUp, ButtonUp,
TriggerZ,
TriggerR,
TriggerL,
ButtonA, ButtonA,
ButtonB, ButtonB,
ButtonX, ButtonX,
ButtonY, ButtonY,
ButtonPlus,
ButtonMinus,
ButtonHome,
ButtonCapture,
ButtonStickL,
ButtonStickR,
TriggerL,
TriggerZL,
TriggerSL,
TriggerR,
TriggerZR,
TriggerSR,
// GC button names
TriggerZ,
ButtonStart, ButtonStart,
// DS4 button names // DS4 button names
@ -316,22 +328,24 @@ class OutputDevice {
public: public:
virtual ~OutputDevice() = default; virtual ~OutputDevice() = default;
virtual void SetLED([[maybe_unused]] const LedStatus& led_status) {} virtual DriverResult SetLED([[maybe_unused]] const LedStatus& led_status) {
return DriverResult::NotSupported;
}
virtual VibrationError SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) { virtual DriverResult SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) {
return VibrationError::NotSupported; return DriverResult::NotSupported;
} }
virtual bool IsVibrationEnabled() { virtual bool IsVibrationEnabled() {
return false; return false;
} }
virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) { virtual DriverResult SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
return PollingError::NotSupported; return DriverResult::NotSupported;
} }
virtual CameraError SetCameraFormat([[maybe_unused]] CameraFormat camera_format) { virtual DriverResult SetCameraFormat([[maybe_unused]] CameraFormat camera_format) {
return CameraError::NotSupported; return DriverResult::NotSupported;
} }
virtual NfcState SupportsNfc() const { virtual NfcState SupportsNfc() const {

View file

@ -483,6 +483,7 @@ struct Values {
Setting<bool> enable_raw_input{false, "enable_raw_input"}; Setting<bool> enable_raw_input{false, "enable_raw_input"};
Setting<bool> controller_navigation{true, "controller_navigation"}; Setting<bool> controller_navigation{true, "controller_navigation"};
Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"};
SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"}; SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"};
SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"}; SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};

View file

@ -30,7 +30,7 @@ std::string ToUpper(std::string str) {
return str; return str;
} }
std::string StringFromBuffer(const std::vector<u8>& data) { std::string StringFromBuffer(std::span<const u8> data) {
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
} }

View file

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <cstddef> #include <cstddef>
#include <span>
#include <string> #include <string>
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
@ -17,7 +18,7 @@ namespace Common {
/// Make a string uppercase /// Make a string uppercase
[[nodiscard]] std::string ToUpper(std::string str); [[nodiscard]] std::string ToUpper(std::string str);
[[nodiscard]] std::string StringFromBuffer(const std::vector<u8>& data); [[nodiscard]] std::string StringFromBuffer(std::span<const u8> data);
[[nodiscard]] std::string StripSpaces(const std::string& s); [[nodiscard]] std::string StripSpaces(const std::string& s);
[[nodiscard]] std::string StripQuotes(const std::string& s); [[nodiscard]] std::string StripQuotes(const std::string& s);

View file

@ -142,9 +142,11 @@ void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
} }
void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data) { std::uintptr_t user_data, bool wait) {
std::scoped_lock scope{basic_lock}; {
const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { std::scoped_lock lk{basic_lock};
const auto itr =
std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
return e.type.lock().get() == event_type.get() && e.user_data == user_data; return e.type.lock().get() == event_type.get() && e.user_data == user_data;
}); });
@ -155,6 +157,12 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
} }
} }
// Force any in-progress events to finish
if (wait) {
std::scoped_lock lk{advance_lock};
}
}
void CoreTiming::AddTicks(u64 ticks_to_add) { void CoreTiming::AddTicks(u64 ticks_to_add) {
ticks += ticks_to_add; ticks += ticks_to_add;
downcount -= static_cast<s64>(ticks); downcount -= static_cast<s64>(ticks);
@ -190,20 +198,6 @@ u64 CoreTiming::GetClockTicks() const {
return CpuCyclesToClockCycles(ticks); return CpuCyclesToClockCycles(ticks);
} }
void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) {
std::scoped_lock lock{basic_lock};
const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
return e.type.lock().get() == event_type.get();
});
// Removing random items breaks the invariant so we have to re-establish it.
if (itr != event_queue.end()) {
event_queue.erase(itr, event_queue.end());
std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
}
std::optional<s64> CoreTiming::Advance() { std::optional<s64> CoreTiming::Advance() {
std::scoped_lock lock{advance_lock, basic_lock}; std::scoped_lock lock{advance_lock, basic_lock};
global_timer = GetGlobalTimeNs().count(); global_timer = GetGlobalTimeNs().count();

View file

@ -98,10 +98,13 @@ public:
const std::shared_ptr<EventType>& event_type, const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data = 0, bool absolute_time = false); std::uintptr_t user_data = 0, bool absolute_time = false);
void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data); void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data,
bool wait = true);
/// We only permit one event of each type in the queue at a time. void UnscheduleEventWithoutWait(const std::shared_ptr<EventType>& event_type,
void RemoveEvent(const std::shared_ptr<EventType>& event_type); std::uintptr_t user_data) {
UnscheduleEvent(event_type, user_data, false);
}
void AddTicks(u64 ticks_to_add); void AddTicks(u64 ticks_to_add);

View file

@ -93,6 +93,7 @@ void EmulatedController::ReloadFromSettings() {
motion_params[index] = Common::ParamPackage(player.motions[index]); motion_params[index] = Common::ParamPackage(player.motions[index]);
} }
controller.color_values = {};
controller.colors_state.fullkey = { controller.colors_state.fullkey = {
.body = GetNpadColor(player.body_color_left), .body = GetNpadColor(player.body_color_left),
.button = GetNpadColor(player.button_color_left), .button = GetNpadColor(player.button_color_left),
@ -106,6 +107,8 @@ void EmulatedController::ReloadFromSettings() {
.button = GetNpadColor(player.button_color_right), .button = GetNpadColor(player.button_color_right),
}; };
ring_params[0] = Common::ParamPackage(Settings::values.ringcon_analogs);
// Other or debug controller should always be a pro controller // Other or debug controller should always be a pro controller
if (npad_id_type != NpadIdType::Other) { if (npad_id_type != NpadIdType::Other) {
SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type)); SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type));
@ -132,18 +135,28 @@ void EmulatedController::LoadDevices() {
trigger_params[LeftIndex] = button_params[Settings::NativeButton::ZL]; trigger_params[LeftIndex] = button_params[Settings::NativeButton::ZL];
trigger_params[RightIndex] = button_params[Settings::NativeButton::ZR]; trigger_params[RightIndex] = button_params[Settings::NativeButton::ZR];
color_params[LeftIndex] = left_joycon;
color_params[RightIndex] = right_joycon;
color_params[LeftIndex].Set("color", true);
color_params[RightIndex].Set("color", true);
battery_params[LeftIndex] = left_joycon; battery_params[LeftIndex] = left_joycon;
battery_params[RightIndex] = right_joycon; battery_params[RightIndex] = right_joycon;
battery_params[LeftIndex].Set("battery", true); battery_params[LeftIndex].Set("battery", true);
battery_params[RightIndex].Set("battery", true); battery_params[RightIndex].Set("battery", true);
camera_params = Common::ParamPackage{"engine:camera,camera:1"}; camera_params[0] = right_joycon;
nfc_params = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"}; camera_params[0].Set("camera", true);
camera_params[1] = Common::ParamPackage{"engine:camera,camera:1"};
ring_params[1] = Common::ParamPackage{"engine:joycon,axis_x:100,axis_y:101"};
nfc_params[0] = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"};
nfc_params[1] = right_joycon;
nfc_params[1].Set("nfc", true);
output_params[LeftIndex] = left_joycon; output_params[LeftIndex] = left_joycon;
output_params[RightIndex] = right_joycon; output_params[RightIndex] = right_joycon;
output_params[2] = camera_params; output_params[2] = camera_params[1];
output_params[3] = nfc_params; output_params[3] = nfc_params[0];
output_params[LeftIndex].Set("output", true); output_params[LeftIndex].Set("output", true);
output_params[RightIndex].Set("output", true); output_params[RightIndex].Set("output", true);
output_params[2].Set("output", true); output_params[2].Set("output", true);
@ -159,8 +172,11 @@ void EmulatedController::LoadDevices() {
Common::Input::CreateInputDevice); Common::Input::CreateInputDevice);
std::ranges::transform(battery_params, battery_devices.begin(), std::ranges::transform(battery_params, battery_devices.begin(),
Common::Input::CreateInputDevice); Common::Input::CreateInputDevice);
camera_devices = Common::Input::CreateInputDevice(camera_params); std::ranges::transform(color_params, color_devices.begin(), Common::Input::CreateInputDevice);
nfc_devices = Common::Input::CreateInputDevice(nfc_params); std::ranges::transform(camera_params, camera_devices.begin(), Common::Input::CreateInputDevice);
std::ranges::transform(ring_params, ring_analog_devices.begin(),
Common::Input::CreateInputDevice);
std::ranges::transform(nfc_params, nfc_devices.begin(), Common::Input::CreateInputDevice);
std::ranges::transform(output_params, output_devices.begin(), std::ranges::transform(output_params, output_devices.begin(),
Common::Input::CreateOutputDevice); Common::Input::CreateOutputDevice);
@ -322,6 +338,19 @@ void EmulatedController::ReloadInput() {
battery_devices[index]->ForceUpdate(); battery_devices[index]->ForceUpdate();
} }
for (std::size_t index = 0; index < color_devices.size(); ++index) {
if (!color_devices[index]) {
continue;
}
color_devices[index]->SetCallback({
.on_change =
[this, index](const Common::Input::CallbackStatus& callback) {
SetColors(callback, index);
},
});
color_devices[index]->ForceUpdate();
}
for (std::size_t index = 0; index < motion_devices.size(); ++index) { for (std::size_t index = 0; index < motion_devices.size(); ++index) {
if (!motion_devices[index]) { if (!motion_devices[index]) {
continue; continue;
@ -335,22 +364,37 @@ void EmulatedController::ReloadInput() {
motion_devices[index]->ForceUpdate(); motion_devices[index]->ForceUpdate();
} }
if (camera_devices) { for (std::size_t index = 0; index < camera_devices.size(); ++index) {
camera_devices->SetCallback({ if (!camera_devices[index]) {
continue;
}
camera_devices[index]->SetCallback({
.on_change = .on_change =
[this](const Common::Input::CallbackStatus& callback) { SetCamera(callback); }, [this](const Common::Input::CallbackStatus& callback) { SetCamera(callback); },
}); });
camera_devices->ForceUpdate(); camera_devices[index]->ForceUpdate();
} }
if (nfc_devices) { for (std::size_t index = 0; index < ring_analog_devices.size(); ++index) {
if (npad_id_type == NpadIdType::Handheld || npad_id_type == NpadIdType::Player1) { if (!ring_analog_devices[index]) {
nfc_devices->SetCallback({ continue;
}
ring_analog_devices[index]->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback) { SetRingAnalog(callback); },
});
ring_analog_devices[index]->ForceUpdate();
}
for (std::size_t index = 0; index < nfc_devices.size(); ++index) {
if (!nfc_devices[index]) {
continue;
}
nfc_devices[index]->SetCallback({
.on_change = .on_change =
[this](const Common::Input::CallbackStatus& callback) { SetNfc(callback); }, [this](const Common::Input::CallbackStatus& callback) { SetNfc(callback); },
}); });
nfc_devices->ForceUpdate(); nfc_devices[index]->ForceUpdate();
}
} }
// Register TAS devices. No need to force update // Register TAS devices. No need to force update
@ -420,6 +464,9 @@ void EmulatedController::UnloadInput() {
for (auto& battery : battery_devices) { for (auto& battery : battery_devices) {
battery.reset(); battery.reset();
} }
for (auto& color : color_devices) {
color.reset();
}
for (auto& output : output_devices) { for (auto& output : output_devices) {
output.reset(); output.reset();
} }
@ -435,8 +482,15 @@ void EmulatedController::UnloadInput() {
for (auto& stick : virtual_stick_devices) { for (auto& stick : virtual_stick_devices) {
stick.reset(); stick.reset();
} }
camera_devices.reset(); for (auto& camera : camera_devices) {
nfc_devices.reset(); camera.reset();
}
for (auto& ring : ring_analog_devices) {
ring.reset();
}
for (auto& nfc : nfc_devices) {
nfc.reset();
}
} }
void EmulatedController::EnableConfiguration() { void EmulatedController::EnableConfiguration() {
@ -448,6 +502,11 @@ void EmulatedController::EnableConfiguration() {
void EmulatedController::DisableConfiguration() { void EmulatedController::DisableConfiguration() {
is_configuring = false; is_configuring = false;
// Get Joycon colors before turning on the controller
for (const auto& color_device : color_devices) {
color_device->ForceUpdate();
}
// Apply temporary npad type to the real controller // Apply temporary npad type to the real controller
if (tmp_npad_type != npad_type) { if (tmp_npad_type != npad_type) {
if (is_connected) { if (is_connected) {
@ -501,6 +560,9 @@ void EmulatedController::SaveCurrentConfig() {
for (std::size_t index = 0; index < player.motions.size(); ++index) { for (std::size_t index = 0; index < player.motions.size(); ++index) {
player.motions[index] = motion_params[index].Serialize(); player.motions[index] = motion_params[index].Serialize();
} }
if (npad_id_type == NpadIdType::Player1) {
Settings::values.ringcon_analogs = ring_params[0].Serialize();
}
} }
void EmulatedController::RestoreConfig() { void EmulatedController::RestoreConfig() {
@ -915,6 +977,58 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
TriggerOnChange(ControllerTriggerType::Motion, true); TriggerOnChange(ControllerTriggerType::Motion, true);
} }
void EmulatedController::SetColors(const Common::Input::CallbackStatus& callback,
std::size_t index) {
if (index >= controller.color_values.size()) {
return;
}
std::unique_lock lock{mutex};
controller.color_values[index] = TransformToColor(callback);
if (is_configuring) {
lock.unlock();
TriggerOnChange(ControllerTriggerType::Color, false);
return;
}
if (controller.color_values[index].body == 0) {
return;
}
controller.colors_state.fullkey = {
.body = GetNpadColor(controller.color_values[index].body),
.button = GetNpadColor(controller.color_values[index].buttons),
};
if (npad_type == NpadStyleIndex::ProController) {
controller.colors_state.left = {
.body = GetNpadColor(controller.color_values[index].left_grip),
.button = GetNpadColor(controller.color_values[index].buttons),
};
controller.colors_state.right = {
.body = GetNpadColor(controller.color_values[index].right_grip),
.button = GetNpadColor(controller.color_values[index].buttons),
};
} else {
switch (index) {
case LeftIndex:
controller.colors_state.left = {
.body = GetNpadColor(controller.color_values[index].body),
.button = GetNpadColor(controller.color_values[index].buttons),
};
break;
case RightIndex:
controller.colors_state.right = {
.body = GetNpadColor(controller.color_values[index].body),
.button = GetNpadColor(controller.color_values[index].buttons),
};
break;
}
}
lock.unlock();
TriggerOnChange(ControllerTriggerType::Color, true);
}
void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback, void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback,
std::size_t index) { std::size_t index) {
if (index >= controller.battery_values.size()) { if (index >= controller.battery_values.size()) {
@ -1005,6 +1119,24 @@ void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback
TriggerOnChange(ControllerTriggerType::IrSensor, true); TriggerOnChange(ControllerTriggerType::IrSensor, true);
} }
void EmulatedController::SetRingAnalog(const Common::Input::CallbackStatus& callback) {
std::unique_lock lock{mutex};
const auto force_value = TransformToStick(callback);
controller.ring_analog_value = force_value.x;
if (is_configuring) {
lock.unlock();
TriggerOnChange(ControllerTriggerType::RingController, false);
return;
}
controller.ring_analog_state.force = force_value.x.value;
lock.unlock();
TriggerOnChange(ControllerTriggerType::RingController, true);
}
void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) { void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) {
std::unique_lock lock{mutex}; std::unique_lock lock{mutex};
controller.nfc_values = TransformToNfc(callback); controller.nfc_values = TransformToNfc(callback);
@ -1053,7 +1185,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
.type = type, .type = type,
}; };
return output_devices[device_index]->SetVibration(status) == return output_devices[device_index]->SetVibration(status) ==
Common::Input::VibrationError::None; Common::Input::DriverResult::Success;
} }
bool EmulatedController::IsVibrationEnabled(std::size_t device_index) { bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
@ -1075,16 +1207,32 @@ bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
return output_devices[device_index]->IsVibrationEnabled(); return output_devices[device_index]->IsVibrationEnabled();
} }
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) { Common::Input::DriverResult EmulatedController::SetPollingMode(
LOG_INFO(Service_HID, "Set polling mode {}", polling_mode); EmulatedDeviceIndex device_index, Common::Input::PollingMode polling_mode) {
auto& output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; LOG_INFO(Service_HID, "Set polling mode {}, device_index={}", polling_mode, device_index);
auto& left_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Left)];
auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_output_device = output_devices[3]; auto& nfc_output_device = output_devices[3];
const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode); if (device_index == EmulatedDeviceIndex::LeftIndex) {
const auto mapped_nfc_result = output_device->SetPollingMode(polling_mode); return left_output_device->SetPollingMode(polling_mode);
}
return virtual_nfc_result == Common::Input::PollingError::None || if (device_index == EmulatedDeviceIndex::RightIndex) {
mapped_nfc_result == Common::Input::PollingError::None; const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
const auto mapped_nfc_result = right_output_device->SetPollingMode(polling_mode);
if (virtual_nfc_result == Common::Input::DriverResult::Success) {
return virtual_nfc_result;
}
return mapped_nfc_result;
}
left_output_device->SetPollingMode(polling_mode);
right_output_device->SetPollingMode(polling_mode);
nfc_output_device->SetPollingMode(polling_mode);
return Common::Input::DriverResult::Success;
} }
bool EmulatedController::SetCameraFormat( bool EmulatedController::SetCameraFormat(
@ -1095,13 +1243,22 @@ bool EmulatedController::SetCameraFormat(
auto& camera_output_device = output_devices[2]; auto& camera_output_device = output_devices[2];
if (right_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>( if (right_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>(
camera_format)) == Common::Input::CameraError::None) { camera_format)) == Common::Input::DriverResult::Success) {
return true; return true;
} }
// Fallback to Qt camera if native device doesn't have support // Fallback to Qt camera if native device doesn't have support
return camera_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>( return camera_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>(
camera_format)) == Common::Input::CameraError::None; camera_format)) == Common::Input::DriverResult::Success;
}
Common::ParamPackage EmulatedController::GetRingParam() const {
return ring_params[0];
}
void EmulatedController::SetRingParam(Common::ParamPackage param) {
ring_params[0] = std::move(param);
ReloadInput();
} }
bool EmulatedController::HasNfc() const { bool EmulatedController::HasNfc() const {
@ -1395,6 +1552,10 @@ CameraValues EmulatedController::GetCameraValues() const {
return controller.camera_values; return controller.camera_values;
} }
RingAnalogValue EmulatedController::GetRingSensorValues() const {
return controller.ring_analog_value;
}
HomeButtonState EmulatedController::GetHomeButtons() const { HomeButtonState EmulatedController::GetHomeButtons() const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
if (is_configuring) { if (is_configuring) {
@ -1478,6 +1639,10 @@ const CameraState& EmulatedController::GetCamera() const {
return controller.camera_state; return controller.camera_state;
} }
RingSensorForce EmulatedController::GetRingSensorForce() const {
return controller.ring_analog_state;
}
const NfcState& EmulatedController::GetNfc() const { const NfcState& EmulatedController::GetNfc() const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
return controller.nfc_state; return controller.nfc_state;

View file

@ -35,19 +35,27 @@ using ControllerMotionDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeMotion::NumMotions>; std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeMotion::NumMotions>;
using TriggerDevices = using TriggerDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeTrigger::NumTriggers>; std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeTrigger::NumTriggers>;
using ColorDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using BatteryDevices = using BatteryDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>; std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using CameraDevices = std::unique_ptr<Common::Input::InputDevice>; using CameraDevices =
using NfcDevices = std::unique_ptr<Common::Input::InputDevice>; std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using RingAnalogDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using NfcDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using OutputDevices = std::array<std::unique_ptr<Common::Input::OutputDevice>, output_devices_size>; using OutputDevices = std::array<std::unique_ptr<Common::Input::OutputDevice>, output_devices_size>;
using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>; using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>; using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>; using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>;
using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>; using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
using ColorParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>; using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using CameraParams = Common::ParamPackage; using CameraParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using NfcParams = Common::ParamPackage; using RingAnalogParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using NfcParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using OutputParams = std::array<Common::ParamPackage, output_devices_size>; using OutputParams = std::array<Common::ParamPackage, output_devices_size>;
using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>; using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>;
@ -58,6 +66,7 @@ using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::Native
using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>; using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>;
using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>; using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>;
using CameraValues = Common::Input::CameraStatus; using CameraValues = Common::Input::CameraStatus;
using RingAnalogValue = Common::Input::AnalogStatus;
using NfcValues = Common::Input::NfcStatus; using NfcValues = Common::Input::NfcStatus;
using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>; using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>;
@ -84,6 +93,10 @@ struct CameraState {
std::size_t sample{}; std::size_t sample{};
}; };
struct RingSensorForce {
f32 force;
};
struct NfcState { struct NfcState {
Common::Input::NfcState state{}; Common::Input::NfcState state{};
std::vector<u8> data{}; std::vector<u8> data{};
@ -116,6 +129,7 @@ struct ControllerStatus {
BatteryValues battery_values{}; BatteryValues battery_values{};
VibrationValues vibration_values{}; VibrationValues vibration_values{};
CameraValues camera_values{}; CameraValues camera_values{};
RingAnalogValue ring_analog_value{};
NfcValues nfc_values{}; NfcValues nfc_values{};
// Data for HID serices // Data for HID serices
@ -129,6 +143,7 @@ struct ControllerStatus {
ControllerColors colors_state{}; ControllerColors colors_state{};
BatteryLevelState battery_state{}; BatteryLevelState battery_state{};
CameraState camera_state{}; CameraState camera_state{};
RingSensorForce ring_analog_state{};
NfcState nfc_state{}; NfcState nfc_state{};
}; };
@ -141,6 +156,7 @@ enum class ControllerTriggerType {
Battery, Battery,
Vibration, Vibration,
IrSensor, IrSensor,
RingController,
Nfc, Nfc,
Connected, Connected,
Disconnected, Disconnected,
@ -294,6 +310,9 @@ public:
/// Returns the latest camera status from the controller with parameters /// Returns the latest camera status from the controller with parameters
CameraValues GetCameraValues() const; CameraValues GetCameraValues() const;
/// Returns the latest status of analog input from the ring sensor with parameters
RingAnalogValue GetRingSensorValues() const;
/// Returns the latest status of button input for the hid::HomeButton service /// Returns the latest status of button input for the hid::HomeButton service
HomeButtonState GetHomeButtons() const; HomeButtonState GetHomeButtons() const;
@ -324,6 +343,9 @@ public:
/// Returns the latest camera status from the controller /// Returns the latest camera status from the controller
const CameraState& GetCamera() const; const CameraState& GetCamera() const;
/// Returns the latest ringcon force sensor value
RingSensorForce GetRingSensorForce() const;
/// Returns the latest ntag status from the controller /// Returns the latest ntag status from the controller
const NfcState& GetNfc() const; const NfcState& GetNfc() const;
@ -341,10 +363,12 @@ public:
/** /**
* Sets the desired data to be polled from a controller * Sets the desired data to be polled from a controller
* @param device_index index of the controller to set the polling mode
* @param polling_mode type of input desired buttons, gyro, nfc, ir, etc. * @param polling_mode type of input desired buttons, gyro, nfc, ir, etc.
* @return true if SetPollingMode was successfull * @return driver result from this command
*/ */
bool SetPollingMode(Common::Input::PollingMode polling_mode); Common::Input::DriverResult SetPollingMode(EmulatedDeviceIndex device_index,
Common::Input::PollingMode polling_mode);
/** /**
* Sets the desired camera format to be polled from a controller * Sets the desired camera format to be polled from a controller
@ -353,6 +377,15 @@ public:
*/ */
bool SetCameraFormat(Core::IrSensor::ImageTransferProcessorFormat camera_format); bool SetCameraFormat(Core::IrSensor::ImageTransferProcessorFormat camera_format);
// Returns the current mapped ring device
Common::ParamPackage GetRingParam() const;
/**
* Updates the current mapped ring device
* @param param ParamPackage with ring sensor data to be mapped
*/
void SetRingParam(Common::ParamPackage param);
/// Returns true if the device has nfc support /// Returns true if the device has nfc support
bool HasNfc() const; bool HasNfc() const;
@ -432,10 +465,17 @@ private:
*/ */
void SetMotion(const Common::Input::CallbackStatus& callback, std::size_t index); void SetMotion(const Common::Input::CallbackStatus& callback, std::size_t index);
/**
* Updates the color status of the controller
* @param callback A CallbackStatus containing the color status
* @param index color ID of the to be updated
*/
void SetColors(const Common::Input::CallbackStatus& callback, std::size_t index);
/** /**
* Updates the battery status of the controller * Updates the battery status of the controller
* @param callback A CallbackStatus containing the battery status * @param callback A CallbackStatus containing the battery status
* @param index Button ID of the to be updated * @param index battery ID of the to be updated
*/ */
void SetBattery(const Common::Input::CallbackStatus& callback, std::size_t index); void SetBattery(const Common::Input::CallbackStatus& callback, std::size_t index);
@ -445,6 +485,12 @@ private:
*/ */
void SetCamera(const Common::Input::CallbackStatus& callback); void SetCamera(const Common::Input::CallbackStatus& callback);
/**
* Updates the ring analog sensor status of the ring controller
* @param callback A CallbackStatus containing the force status
*/
void SetRingAnalog(const Common::Input::CallbackStatus& callback);
/** /**
* Updates the nfc status of the controller * Updates the nfc status of the controller
* @param callback A CallbackStatus containing the nfc status * @param callback A CallbackStatus containing the nfc status
@ -484,7 +530,9 @@ private:
ControllerMotionParams motion_params; ControllerMotionParams motion_params;
TriggerParams trigger_params; TriggerParams trigger_params;
BatteryParams battery_params; BatteryParams battery_params;
ColorParams color_params;
CameraParams camera_params; CameraParams camera_params;
RingAnalogParams ring_params;
NfcParams nfc_params; NfcParams nfc_params;
OutputParams output_params; OutputParams output_params;
@ -493,7 +541,9 @@ private:
ControllerMotionDevices motion_devices; ControllerMotionDevices motion_devices;
TriggerDevices trigger_devices; TriggerDevices trigger_devices;
BatteryDevices battery_devices; BatteryDevices battery_devices;
ColorDevices color_devices;
CameraDevices camera_devices; CameraDevices camera_devices;
RingAnalogDevices ring_analog_devices;
NfcDevices nfc_devices; NfcDevices nfc_devices;
OutputDevices output_devices; OutputDevices output_devices;

View file

@ -14,7 +14,6 @@ EmulatedDevices::EmulatedDevices() = default;
EmulatedDevices::~EmulatedDevices() = default; EmulatedDevices::~EmulatedDevices() = default;
void EmulatedDevices::ReloadFromSettings() { void EmulatedDevices::ReloadFromSettings() {
ring_params = Common::ParamPackage(Settings::values.ringcon_analogs);
ReloadInput(); ReloadInput();
} }
@ -66,8 +65,6 @@ void EmulatedDevices::ReloadInput() {
key_index++; key_index++;
} }
ring_analog_device = Common::Input::CreateInputDevice(ring_params);
for (std::size_t index = 0; index < mouse_button_devices.size(); ++index) { for (std::size_t index = 0; index < mouse_button_devices.size(); ++index) {
if (!mouse_button_devices[index]) { if (!mouse_button_devices[index]) {
continue; continue;
@ -122,13 +119,6 @@ void EmulatedDevices::ReloadInput() {
}, },
}); });
} }
if (ring_analog_device) {
ring_analog_device->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback) { SetRingAnalog(callback); },
});
}
} }
void EmulatedDevices::UnloadInput() { void EmulatedDevices::UnloadInput() {
@ -145,7 +135,6 @@ void EmulatedDevices::UnloadInput() {
for (auto& button : keyboard_modifier_devices) { for (auto& button : keyboard_modifier_devices) {
button.reset(); button.reset();
} }
ring_analog_device.reset();
} }
void EmulatedDevices::EnableConfiguration() { void EmulatedDevices::EnableConfiguration() {
@ -165,7 +154,6 @@ void EmulatedDevices::SaveCurrentConfig() {
if (!is_configuring) { if (!is_configuring) {
return; return;
} }
Settings::values.ringcon_analogs = ring_params.Serialize();
} }
void EmulatedDevices::RestoreConfig() { void EmulatedDevices::RestoreConfig() {
@ -175,15 +163,6 @@ void EmulatedDevices::RestoreConfig() {
ReloadFromSettings(); ReloadFromSettings();
} }
Common::ParamPackage EmulatedDevices::GetRingParam() const {
return ring_params;
}
void EmulatedDevices::SetRingParam(Common::ParamPackage param) {
ring_params = std::move(param);
ReloadInput();
}
void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& callback, void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& callback,
std::size_t index) { std::size_t index) {
if (index >= device_status.keyboard_values.size()) { if (index >= device_status.keyboard_values.size()) {
@ -430,23 +409,6 @@ void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callbac
TriggerOnChange(DeviceTriggerType::Mouse); TriggerOnChange(DeviceTriggerType::Mouse);
} }
void EmulatedDevices::SetRingAnalog(const Common::Input::CallbackStatus& callback) {
std::lock_guard lock{mutex};
const auto force_value = TransformToStick(callback);
device_status.ring_analog_value = force_value.x;
if (is_configuring) {
device_status.ring_analog_value = {};
TriggerOnChange(DeviceTriggerType::RingController);
return;
}
device_status.ring_analog_state.force = force_value.x.value;
TriggerOnChange(DeviceTriggerType::RingController);
}
KeyboardValues EmulatedDevices::GetKeyboardValues() const { KeyboardValues EmulatedDevices::GetKeyboardValues() const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
return device_status.keyboard_values; return device_status.keyboard_values;
@ -462,10 +424,6 @@ MouseButtonValues EmulatedDevices::GetMouseButtonsValues() const {
return device_status.mouse_button_values; return device_status.mouse_button_values;
} }
RingAnalogValue EmulatedDevices::GetRingSensorValues() const {
return device_status.ring_analog_value;
}
KeyboardKey EmulatedDevices::GetKeyboard() const { KeyboardKey EmulatedDevices::GetKeyboard() const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
return device_status.keyboard_state; return device_status.keyboard_state;
@ -491,10 +449,6 @@ AnalogStickState EmulatedDevices::GetMouseWheel() const {
return device_status.mouse_wheel_state; return device_status.mouse_wheel_state;
} }
RingSensorForce EmulatedDevices::GetRingSensorForce() const {
return device_status.ring_analog_state;
}
void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) { void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) {
std::scoped_lock lock{callback_mutex}; std::scoped_lock lock{callback_mutex};
for (const auto& poller_pair : callback_list) { for (const auto& poller_pair : callback_list) {

View file

@ -26,11 +26,9 @@ using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice
using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseWheel::NumMouseWheels>; Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>; using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>;
using RingAnalogDevice = std::unique_ptr<Common::Input::InputDevice>;
using MouseButtonParams = using MouseButtonParams =
std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>; std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>;
using RingAnalogParams = Common::ParamPackage;
using KeyboardValues = using KeyboardValues =
std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardKeys>; std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardKeys>;
@ -41,17 +39,12 @@ using MouseButtonValues =
using MouseAnalogValues = using MouseAnalogValues =
std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>; std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickValue = Common::Input::TouchStatus; using MouseStickValue = Common::Input::TouchStatus;
using RingAnalogValue = Common::Input::AnalogStatus;
struct MousePosition { struct MousePosition {
f32 x; f32 x;
f32 y; f32 y;
}; };
struct RingSensorForce {
f32 force;
};
struct DeviceStatus { struct DeviceStatus {
// Data from input_common // Data from input_common
KeyboardValues keyboard_values{}; KeyboardValues keyboard_values{};
@ -59,7 +52,6 @@ struct DeviceStatus {
MouseButtonValues mouse_button_values{}; MouseButtonValues mouse_button_values{};
MouseAnalogValues mouse_analog_values{}; MouseAnalogValues mouse_analog_values{};
MouseStickValue mouse_stick_value{}; MouseStickValue mouse_stick_value{};
RingAnalogValue ring_analog_value{};
// Data for HID serices // Data for HID serices
KeyboardKey keyboard_state{}; KeyboardKey keyboard_state{};
@ -67,7 +59,6 @@ struct DeviceStatus {
MouseButton mouse_button_state{}; MouseButton mouse_button_state{};
MousePosition mouse_position_state{}; MousePosition mouse_position_state{};
AnalogStickState mouse_wheel_state{}; AnalogStickState mouse_wheel_state{};
RingSensorForce ring_analog_state{};
}; };
enum class DeviceTriggerType { enum class DeviceTriggerType {
@ -138,9 +129,6 @@ public:
/// Returns the latest status of button input from the mouse with parameters /// Returns the latest status of button input from the mouse with parameters
MouseButtonValues GetMouseButtonsValues() const; MouseButtonValues GetMouseButtonsValues() const;
/// Returns the latest status of analog input from the ring sensor with parameters
RingAnalogValue GetRingSensorValues() const;
/// Returns the latest status of button input from the keyboard /// Returns the latest status of button input from the keyboard
KeyboardKey GetKeyboard() const; KeyboardKey GetKeyboard() const;
@ -156,9 +144,6 @@ public:
/// Returns the latest mouse wheel change /// Returns the latest mouse wheel change
AnalogStickState GetMouseWheel() const; AnalogStickState GetMouseWheel() const;
/// Returns the latest ringcon force sensor value
RingSensorForce GetRingSensorForce() const;
/** /**
* Adds a callback to the list of events * Adds a callback to the list of events
* @param update_callback InterfaceUpdateCallback that will be triggered * @param update_callback InterfaceUpdateCallback that will be triggered
@ -224,14 +209,11 @@ private:
bool is_configuring{false}; bool is_configuring{false};
RingAnalogParams ring_params;
KeyboardDevices keyboard_devices; KeyboardDevices keyboard_devices;
KeyboardModifierDevices keyboard_modifier_devices; KeyboardModifierDevices keyboard_modifier_devices;
MouseButtonDevices mouse_button_devices; MouseButtonDevices mouse_button_devices;
MouseAnalogDevices mouse_analog_devices; MouseAnalogDevices mouse_analog_devices;
MouseStickDevice mouse_stick_device; MouseStickDevice mouse_stick_device;
RingAnalogDevice ring_analog_device;
mutable std::mutex mutex; mutable std::mutex mutex;
mutable std::mutex callback_mutex; mutable std::mutex callback_mutex;

View file

@ -304,6 +304,18 @@ Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& cal
return nfc; return nfc;
} }
Common::Input::BodyColorStatus TransformToColor(const Common::Input::CallbackStatus& callback) {
switch (callback.type) {
case Common::Input::InputType::Color:
return callback.color_status;
break;
default:
LOG_ERROR(Input, "Conversion from type {} to color not implemented", callback.type);
return {};
break;
}
}
void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) { void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) {
const auto& properties = analog.properties; const auto& properties = analog.properties;
float& raw_value = analog.raw_value; float& raw_value = analog.raw_value;

View file

@ -88,10 +88,18 @@ Common::Input::CameraStatus TransformToCamera(const Common::Input::CallbackStatu
* Converts raw input data into a valid nfc status. * Converts raw input data into a valid nfc status.
* *
* @param callback Supported callbacks: Nfc. * @param callback Supported callbacks: Nfc.
* @return A valid CameraObject object. * @return A valid data tag vector.
*/ */
Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& callback); Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& callback);
/**
* Converts raw input data into a valid color status.
*
* @param callback Supported callbacks: Color.
* @return A valid Color object.
*/
Common::Input::BodyColorStatus TransformToColor(const Common::Input::CallbackStatus& callback);
/** /**
* Converts raw analog data into a valid analog value * Converts raw analog data into a valid analog value
* @param analog An analog object containing raw data and properties * @param analog An analog object containing raw data and properties

View file

@ -11,6 +11,7 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/scratch_buffer.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_auto_object.h"
@ -325,7 +326,7 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_threa
return ResultSuccess; return ResultSuccess;
} }
std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { std::vector<u8> HLERequestContext::ReadBufferCopy(std::size_t buffer_index) const {
const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
BufferDescriptorA()[buffer_index].Size()}; BufferDescriptorA()[buffer_index].Size()};
if (is_buffer_a) { if (is_buffer_a) {
@ -345,6 +346,33 @@ std::vector<u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const {
} }
} }
std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const {
static thread_local std::array<Common::ScratchBuffer<u8>, 2> read_buffer_a;
static thread_local std::array<Common::ScratchBuffer<u8>, 2> read_buffer_x;
const bool is_buffer_a{BufferDescriptorA().size() > buffer_index &&
BufferDescriptorA()[buffer_index].Size()};
if (is_buffer_a) {
ASSERT_OR_EXECUTE_MSG(
BufferDescriptorA().size() > buffer_index, { return {}; },
"BufferDescriptorA invalid buffer_index {}", buffer_index);
auto& read_buffer = read_buffer_a[buffer_index];
read_buffer.resize_destructive(BufferDescriptorA()[buffer_index].Size());
memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), read_buffer.data(),
read_buffer.size());
return read_buffer;
} else {
ASSERT_OR_EXECUTE_MSG(
BufferDescriptorX().size() > buffer_index, { return {}; },
"BufferDescriptorX invalid buffer_index {}", buffer_index);
auto& read_buffer = read_buffer_x[buffer_index];
read_buffer.resize_destructive(BufferDescriptorX()[buffer_index].Size());
memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), read_buffer.data(),
read_buffer.size());
return read_buffer;
}
}
std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size, std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
std::size_t buffer_index) const { std::size_t buffer_index) const {
if (size == 0) { if (size == 0) {

View file

@ -7,6 +7,7 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <span>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
@ -270,8 +271,11 @@ public:
return domain_message_header.has_value(); return domain_message_header.has_value();
} }
/// Helper function to read a buffer using the appropriate buffer descriptor /// Helper function to get a span of a buffer using the appropriate buffer descriptor
[[nodiscard]] std::vector<u8> ReadBuffer(std::size_t buffer_index = 0) const; [[nodiscard]] std::span<const u8> ReadBuffer(std::size_t buffer_index = 0) const;
/// Helper function to read a copy of a buffer using the appropriate buffer descriptor
[[nodiscard]] std::vector<u8> ReadBufferCopy(std::size_t buffer_index = 0) const;
/// Helper function to write a buffer using the appropriate buffer descriptor /// Helper function to write a buffer using the appropriate buffer descriptor
std::size_t WriteBuffer(const void* buffer, std::size_t size, std::size_t WriteBuffer(const void* buffer, std::size_t size,

View file

@ -18,7 +18,8 @@ void KHardwareTimer::Initialize() {
} }
void KHardwareTimer::Finalize() { void KHardwareTimer::Finalize() {
this->DisableInterrupt(); m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type, reinterpret_cast<uintptr_t>(this));
m_wakeup_time = std::numeric_limits<s64>::max();
m_event_type.reset(); m_event_type.reset();
} }
@ -59,7 +60,8 @@ void KHardwareTimer::EnableInterrupt(s64 wakeup_time) {
} }
void KHardwareTimer::DisableInterrupt() { void KHardwareTimer::DisableInterrupt() {
m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type, reinterpret_cast<uintptr_t>(this)); m_kernel.System().CoreTiming().UnscheduleEventWithoutWait(m_event_type,
reinterpret_cast<uintptr_t>(this));
m_wakeup_time = std::numeric_limits<s64>::max(); m_wakeup_time = std::numeric_limits<s64>::max();
} }

View file

@ -1124,7 +1124,7 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const u64 offset{rp.Pop<u64>()}; const u64 offset{rp.Pop<u64>()};
const std::vector<u8> data{ctx.ReadBuffer()}; const auto data{ctx.ReadBuffer()};
const std::size_t size{std::min<u64>(data.size(), backing.GetSize() - offset)}; const std::size_t size{std::min<u64>(data.size(), backing.GetSize() - offset)};
LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, size); LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, size);

View file

@ -112,7 +112,7 @@ private:
void RequestUpdate(Kernel::HLERequestContext& ctx) { void RequestUpdate(Kernel::HLERequestContext& ctx) {
LOG_TRACE(Service_Audio, "called"); LOG_TRACE(Service_Audio, "called");
std::vector<u8> input{ctx.ReadBuffer(0)}; const auto input{ctx.ReadBuffer(0)};
// These buffers are written manually to avoid an issue with WriteBuffer throwing errors for // These buffers are written manually to avoid an issue with WriteBuffer throwing errors for
// checking size 0. Performance size is 0 for most games. // checking size 0. Performance size is 0 for most games.

View file

@ -93,7 +93,7 @@ private:
ctx.WriteBuffer(samples); ctx.WriteBuffer(samples);
} }
bool DecodeOpusData(u32& consumed, u32& sample_count, const std::vector<u8>& input, bool DecodeOpusData(u32& consumed, u32& sample_count, std::span<const u8> input,
std::vector<opus_int16>& output, u64* out_performance_time) const { std::vector<opus_int16>& output, u64* out_performance_time) const {
const auto start_time = std::chrono::steady_clock::now(); const auto start_time = std::chrono::steady_clock::now();
const std::size_t raw_output_sz = output.size() * sizeof(opus_int16); const std::size_t raw_output_sz = output.size() * sizeof(opus_int16);

View file

@ -122,7 +122,7 @@ private:
void ImportTicket(Kernel::HLERequestContext& ctx) { void ImportTicket(Kernel::HLERequestContext& ctx) {
const auto ticket = ctx.ReadBuffer(); const auto ticket = ctx.ReadBuffer();
const auto cert = ctx.ReadBuffer(1); [[maybe_unused]] const auto cert = ctx.ReadBuffer(1);
if (ticket.size() < sizeof(Core::Crypto::Ticket)) { if (ticket.size() < sizeof(Core::Crypto::Ticket)) {
LOG_ERROR(Service_ETicket, "The input buffer is not large enough!"); LOG_ERROR(Service_ETicket, "The input buffer is not large enough!");

View file

@ -190,7 +190,7 @@ private:
return; return;
} }
const std::vector<u8> data = ctx.ReadBuffer(); const auto data = ctx.ReadBuffer();
ASSERT_MSG( ASSERT_MSG(
static_cast<s64>(data.size()) <= length, static_cast<s64>(data.size()) <= length,
@ -401,11 +401,8 @@ public:
} }
void RenameFile(Kernel::HLERequestContext& ctx) { void RenameFile(Kernel::HLERequestContext& ctx) {
std::vector<u8> buffer = ctx.ReadBuffer(0); const std::string src_name = Common::StringFromBuffer(ctx.ReadBuffer(0));
const std::string src_name = Common::StringFromBuffer(buffer); const std::string dst_name = Common::StringFromBuffer(ctx.ReadBuffer(1));
buffer = ctx.ReadBuffer(1);
const std::string dst_name = Common::StringFromBuffer(buffer);
LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", src_name, dst_name); LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", src_name, dst_name);

View file

@ -228,7 +228,8 @@ private:
return; return;
} }
control = ctx.ReadBuffer(); // TODO: Can this be a span?
control = ctx.ReadBufferCopy();
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);

View file

@ -272,6 +272,8 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
} }
break; break;
case Core::HID::NpadStyleIndex::JoyconLeft: case Core::HID::NpadStyleIndex::JoyconLeft:
shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
shared_memory->fullkey_color.fullkey = body_colors.left;
shared_memory->joycon_color.attribute = ColorAttribute::Ok; shared_memory->joycon_color.attribute = ColorAttribute::Ok;
shared_memory->joycon_color.left = body_colors.left; shared_memory->joycon_color.left = body_colors.left;
shared_memory->battery_level_dual = battery_level.left.battery_level; shared_memory->battery_level_dual = battery_level.left.battery_level;
@ -285,6 +287,8 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1); shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1);
break; break;
case Core::HID::NpadStyleIndex::JoyconRight: case Core::HID::NpadStyleIndex::JoyconRight:
shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
shared_memory->fullkey_color.fullkey = body_colors.right;
shared_memory->joycon_color.attribute = ColorAttribute::Ok; shared_memory->joycon_color.attribute = ColorAttribute::Ok;
shared_memory->joycon_color.right = body_colors.right; shared_memory->joycon_color.right = body_colors.right;
shared_memory->battery_level_right = battery_level.right.battery_level; shared_memory->battery_level_right = battery_level.right.battery_level;
@ -332,6 +336,20 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
controller.is_connected = true; controller.is_connected = true;
controller.device->Connect(); controller.device->Connect();
controller.device->SetLedPattern();
if (controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
if (controller.is_dual_left_connected) {
controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::LeftIndex,
Common::Input::PollingMode::Active);
}
if (controller.is_dual_right_connected) {
controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
}
} else {
controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices,
Common::Input::PollingMode::Active);
}
SignalStyleSetChangedEvent(npad_id); SignalStyleSetChangedEvent(npad_id);
WriteEmptyEntry(controller.shared_memory); WriteEmptyEntry(controller.shared_memory);
} }
@ -737,11 +755,12 @@ Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const {
return hid_core.GetSupportedStyleTag(); return hid_core.GetSupportedStyleTag();
} }
void Controller_NPad::SetSupportedNpadIdTypes(u8* data, std::size_t length) { void Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
const auto length = data.size();
ASSERT(length > 0 && (length % sizeof(u32)) == 0); ASSERT(length > 0 && (length % sizeof(u32)) == 0);
supported_npad_id_types.clear(); supported_npad_id_types.clear();
supported_npad_id_types.resize(length / sizeof(u32)); supported_npad_id_types.resize(length / sizeof(u32));
std::memcpy(supported_npad_id_types.data(), data, length); std::memcpy(supported_npad_id_types.data(), data.data(), length);
} }
void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {

View file

@ -6,6 +6,7 @@
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <mutex> #include <mutex>
#include <span>
#include "common/bit_field.h" #include "common/bit_field.h"
#include "common/common_types.h" #include "common/common_types.h"
@ -95,7 +96,7 @@ public:
void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
Core::HID::NpadStyleTag GetSupportedStyleSet() const; Core::HID::NpadStyleTag GetSupportedStyleSet() const;
void SetSupportedNpadIdTypes(u8* data, std::size_t length); void SetSupportedNpadIdTypes(std::span<const u8> data);
void GetSupportedNpadIdTypes(u32* data, std::size_t max_length); void GetSupportedNpadIdTypes(u32* data, std::size_t max_length);
std::size_t GetSupportedNpadIdTypesSize() const; std::size_t GetSupportedNpadIdTypesSize() const;

View file

@ -1026,7 +1026,7 @@ void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()}; const auto applet_resource_user_id{rp.Pop<u64>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad) applet_resource->GetController<Controller_NPad>(HidController::NPad)
.SetSupportedNpadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize()); .SetSupportedNpadIdTypes(ctx.ReadBuffer());
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
@ -2104,7 +2104,7 @@ void Hid::WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx) {
const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
const auto unknown{rp.Pop<u64>()}; const auto unknown{rp.Pop<u64>()};
const auto buffer = ctx.ReadBuffer(); [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}", LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}",
connection_handle.npad_id, unknown); connection_handle.npad_id, unknown);

View file

@ -297,7 +297,7 @@ void HidBus::EnableExternalDevice(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()}; const auto parameters{rp.PopRaw<Parameters>()};
LOG_INFO(Service_HID, LOG_DEBUG(Service_HID,
"called, enable={}, abstracted_pad_id={}, bus_type={}, internal_index={}, " "called, enable={}, abstracted_pad_id={}, bus_type={}, internal_index={}, "
"player_number={}, is_valid={}, inval={}, applet_resource_user_id{}", "player_number={}, is_valid={}, inval={}, applet_resource_user_id{}",
parameters.enable, parameters.bus_handle.abstracted_pad_id, parameters.enable, parameters.bus_handle.abstracted_pad_id,
@ -326,7 +326,7 @@ void HidBus::GetExternalDeviceId(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto bus_handle_{rp.PopRaw<BusHandle>()}; const auto bus_handle_{rp.PopRaw<BusHandle>()};
LOG_INFO(Service_HID, LOG_DEBUG(Service_HID,
"called, abstracted_pad_id={}, bus_type={}, internal_index={}, player_number={}, " "called, abstracted_pad_id={}, bus_type={}, internal_index={}, player_number={}, "
"is_valid={}", "is_valid={}",
bus_handle_.abstracted_pad_id, bus_handle_.bus_type, bus_handle_.internal_index, bus_handle_.abstracted_pad_id, bus_handle_.bus_type, bus_handle_.internal_index,

View file

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <array> #include <array>
#include <span>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/result.h" #include "core/hle/result.h"
@ -150,7 +151,7 @@ public:
} }
// Assigns a command from data // Assigns a command from data
virtual bool SetCommand(const std::vector<u8>& data) { virtual bool SetCommand(std::span<const u8> data) {
return {}; return {};
} }

View file

@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hid/emulated_devices.h" #include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h" #include "core/hid/hid_core.h"
#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_readable_event.h"
@ -12,16 +12,20 @@ namespace Service::HID {
RingController::RingController(Core::HID::HIDCore& hid_core_, RingController::RingController(Core::HID::HIDCore& hid_core_,
KernelHelpers::ServiceContext& service_context_) KernelHelpers::ServiceContext& service_context_)
: HidbusBase(service_context_) { : HidbusBase(service_context_) {
input = hid_core_.GetEmulatedDevices(); input = hid_core_.GetEmulatedController(Core::HID::NpadIdType::Player1);
} }
RingController::~RingController() = default; RingController::~RingController() = default;
void RingController::OnInit() { void RingController::OnInit() {
input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Ring);
return; return;
} }
void RingController::OnRelease() { void RingController::OnRelease() {
input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
return; return;
}; };
@ -112,7 +116,7 @@ std::vector<u8> RingController::GetReply() const {
} }
} }
bool RingController::SetCommand(const std::vector<u8>& data) { bool RingController::SetCommand(std::span<const u8> data) {
if (data.size() < 4) { if (data.size() < 4) {
LOG_ERROR(Service_HID, "Command size not supported {}", data.size()); LOG_ERROR(Service_HID, "Command size not supported {}", data.size());
command = RingConCommands::Error; command = RingConCommands::Error;

View file

@ -4,12 +4,13 @@
#pragma once #pragma once
#include <array> #include <array>
#include <span>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/service/hid/hidbus/hidbus_base.h" #include "core/hle/service/hid/hidbus/hidbus_base.h"
namespace Core::HID { namespace Core::HID {
class EmulatedDevices; class EmulatedController;
} // namespace Core::HID } // namespace Core::HID
namespace Service::HID { namespace Service::HID {
@ -31,7 +32,7 @@ public:
u8 GetDeviceId() const override; u8 GetDeviceId() const override;
// Assigns a command from data // Assigns a command from data
bool SetCommand(const std::vector<u8>& data) override; bool SetCommand(std::span<const u8> data) override;
// Returns a reply from a command // Returns a reply from a command
std::vector<u8> GetReply() const override; std::vector<u8> GetReply() const override;
@ -248,6 +249,6 @@ private:
.zero = {.value = idle_value, .crc = 225}, .zero = {.value = idle_value, .crc = 225},
}; };
Core::HID::EmulatedDevices* input; Core::HID::EmulatedController* input;
}; };
} // namespace Service::HID } // namespace Service::HID

View file

@ -42,7 +42,7 @@ std::vector<u8> Starlink::GetReply() const {
return {}; return {};
} }
bool Starlink::SetCommand(const std::vector<u8>& data) { bool Starlink::SetCommand(std::span<const u8> data) {
LOG_ERROR(Service_HID, "Command not implemented"); LOG_ERROR(Service_HID, "Command not implemented");
return false; return false;
} }

View file

@ -29,7 +29,7 @@ public:
u8 GetDeviceId() const override; u8 GetDeviceId() const override;
// Assigns a command from data // Assigns a command from data
bool SetCommand(const std::vector<u8>& data) override; bool SetCommand(std::span<const u8> data) override;
// Returns a reply from a command // Returns a reply from a command
std::vector<u8> GetReply() const override; std::vector<u8> GetReply() const override;

View file

@ -43,7 +43,7 @@ std::vector<u8> HidbusStubbed::GetReply() const {
return {}; return {};
} }
bool HidbusStubbed::SetCommand(const std::vector<u8>& data) { bool HidbusStubbed::SetCommand(std::span<const u8> data) {
LOG_ERROR(Service_HID, "Command not implemented"); LOG_ERROR(Service_HID, "Command not implemented");
return false; return false;
} }

View file

@ -29,7 +29,7 @@ public:
u8 GetDeviceId() const override; u8 GetDeviceId() const override;
// Assigns a command from data // Assigns a command from data
bool SetCommand(const std::vector<u8>& data) override; bool SetCommand(std::span<const u8> data) override;
// Returns a reply from a command // Returns a reply from a command
std::vector<u8> GetReply() const override; std::vector<u8> GetReply() const override;

View file

@ -108,6 +108,8 @@ void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
auto result = IsIrCameraHandleValid(parameters.camera_handle); auto result = IsIrCameraHandleValid(parameters.camera_handle);
if (result.IsSuccess()) { if (result.IsSuccess()) {
// TODO: Stop Image processor // TODO: Stop Image processor
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
result = ResultSuccess; result = ResultSuccess;
} }
@ -139,6 +141,8 @@ void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
MakeProcessor<MomentProcessor>(parameters.camera_handle, device); MakeProcessor<MomentProcessor>(parameters.camera_handle, device);
auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle); auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle);
image_transfer_processor.SetConfig(parameters.processor_config); image_transfer_processor.SetConfig(parameters.processor_config);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
} }
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -170,6 +174,8 @@ void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
auto& image_transfer_processor = auto& image_transfer_processor =
GetProcessor<ClusteringProcessor>(parameters.camera_handle); GetProcessor<ClusteringProcessor>(parameters.camera_handle);
image_transfer_processor.SetConfig(parameters.processor_config); image_transfer_processor.SetConfig(parameters.processor_config);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
} }
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -219,6 +225,8 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
GetProcessor<ImageTransferProcessor>(parameters.camera_handle); GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
image_transfer_processor.SetConfig(parameters.processor_config); image_transfer_processor.SetConfig(parameters.processor_config);
image_transfer_processor.SetTransferMemoryPointer(transfer_memory); image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
} }
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -294,6 +302,8 @@ void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
auto& image_transfer_processor = auto& image_transfer_processor =
GetProcessor<TeraPluginProcessor>(parameters.camera_handle); GetProcessor<TeraPluginProcessor>(parameters.camera_handle);
image_transfer_processor.SetConfig(parameters.processor_config); image_transfer_processor.SetConfig(parameters.processor_config);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
} }
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -343,6 +353,8 @@ void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
MakeProcessor<PointingProcessor>(camera_handle, device); MakeProcessor<PointingProcessor>(camera_handle, device);
auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle); auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle);
image_transfer_processor.SetConfig(processor_config); image_transfer_processor.SetConfig(processor_config);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
} }
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -453,6 +465,8 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
GetProcessor<ImageTransferProcessor>(parameters.camera_handle); GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
image_transfer_processor.SetConfig(parameters.processor_config); image_transfer_processor.SetConfig(parameters.processor_config);
image_transfer_processor.SetTransferMemoryPointer(transfer_memory); image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
} }
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -479,6 +493,8 @@ void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
MakeProcessor<IrLedProcessor>(camera_handle, device); MakeProcessor<IrLedProcessor>(camera_handle, device);
auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle); auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle);
image_transfer_processor.SetConfig(processor_config); image_transfer_processor.SetConfig(processor_config);
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::IR);
} }
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
@ -504,6 +520,8 @@ void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
auto result = IsIrCameraHandleValid(parameters.camera_handle); auto result = IsIrCameraHandleValid(parameters.camera_handle);
if (result.IsSuccess()) { if (result.IsSuccess()) {
// TODO: Stop image processor async // TODO: Stop image processor async
npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
result = ResultSuccess; result = ResultSuccess;
} }

View file

@ -62,7 +62,7 @@ public:
const auto parameters{rp.PopRaw<InputParameters>()}; const auto parameters{rp.PopRaw<InputParameters>()};
// Optional input/output buffers // Optional input/output buffers
std::vector<u8> input_buffer{ctx.CanReadBuffer() ? ctx.ReadBuffer() : std::vector<u8>()}; const auto input_buffer{ctx.CanReadBuffer() ? ctx.ReadBuffer() : std::span<const u8>()};
std::vector<u8> output_buffer(ctx.CanWriteBuffer() ? ctx.GetWriteBufferSize() : 0); std::vector<u8> output_buffer(ctx.CanWriteBuffer() ? ctx.GetWriteBufferSize() : 0);
// Function call prototype: // Function call prototype:
@ -132,7 +132,7 @@ public:
const auto command{rp.PopRaw<u64>()}; const auto command{rp.PopRaw<u64>()};
// Optional input/output buffers // Optional input/output buffers
std::vector<u8> input_buffer{ctx.CanReadBuffer() ? ctx.ReadBuffer() : std::vector<u8>()}; const auto input_buffer{ctx.CanReadBuffer() ? ctx.ReadBuffer() : std::span<const u8>()};
std::vector<u8> output_buffer(ctx.CanWriteBuffer() ? ctx.GetWriteBufferSize() : 0); std::vector<u8> output_buffer(ctx.CanWriteBuffer() ? ctx.GetWriteBufferSize() : 0);
// Function call prototype: // Function call prototype:

View file

@ -427,7 +427,7 @@ public:
} }
void SetAdvertiseData(Kernel::HLERequestContext& ctx) { void SetAdvertiseData(Kernel::HLERequestContext& ctx) {
std::vector<u8> read_buffer = ctx.ReadBuffer(); const auto read_buffer = ctx.ReadBuffer();
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(lan_discovery.SetAdvertiseData(read_buffer)); rb.Push(lan_discovery.SetAdvertiseData(read_buffer));
@ -479,7 +479,7 @@ public:
parameters.security_config.passphrase_size, parameters.security_config.passphrase_size,
parameters.security_config.security_mode, parameters.local_communication_version); parameters.security_config.security_mode, parameters.local_communication_version);
const std::vector<u8> read_buffer = ctx.ReadBuffer(); const auto read_buffer = ctx.ReadBuffer();
if (read_buffer.size() != sizeof(NetworkInfo)) { if (read_buffer.size() != sizeof(NetworkInfo)) {
LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!"); LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!");
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};

View file

@ -130,7 +130,9 @@ Result NfcDevice::StartDetection(NFP::TagProtocol allowed_protocol) {
return WrongDeviceState; return WrongDeviceState;
} }
if (!npad_device->SetPollingMode(Common::Input::PollingMode::NFC)) { if (npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::NFC) !=
Common::Input::DriverResult::Success) {
LOG_ERROR(Service_NFC, "Nfc not supported"); LOG_ERROR(Service_NFC, "Nfc not supported");
return NfcDisabled; return NfcDisabled;
} }
@ -141,7 +143,8 @@ Result NfcDevice::StartDetection(NFP::TagProtocol allowed_protocol) {
} }
Result NfcDevice::StopDetection() { Result NfcDevice::StopDetection() {
npad_device->SetPollingMode(Common::Input::PollingMode::Active); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
if (device_state == NFP::DeviceState::Initialized) { if (device_state == NFP::DeviceState::Initialized) {
return ResultSuccess; return ResultSuccess;

View file

@ -152,7 +152,9 @@ Result NfpDevice::StartDetection(TagProtocol allowed_protocol) {
return WrongDeviceState; return WrongDeviceState;
} }
if (!npad_device->SetPollingMode(Common::Input::PollingMode::NFC)) { if (npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::NFC) !=
Common::Input::DriverResult::Success) {
LOG_ERROR(Service_NFP, "Nfc not supported"); LOG_ERROR(Service_NFP, "Nfc not supported");
return NfcDisabled; return NfcDisabled;
} }
@ -163,7 +165,8 @@ Result NfpDevice::StartDetection(TagProtocol allowed_protocol) {
} }
Result NfpDevice::StopDetection() { Result NfpDevice::StopDetection() {
npad_device->SetPollingMode(Common::Input::PollingMode::Active); npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
Common::Input::PollingMode::Active);
if (device_state == DeviceState::Initialized) { if (device_state == DeviceState::Initialized) {
return ResultSuccess; return ResultSuccess;

View file

@ -3,7 +3,9 @@
#pragma once #pragma once
#include <span>
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/service/nvdrv/nvdata.h" #include "core/hle/service/nvdrv/nvdata.h"
@ -31,7 +33,7 @@ public:
* @param output A buffer where the output data will be written to. * @param output A buffer where the output data will be written to.
* @returns The result code of the ioctl. * @returns The result code of the ioctl.
*/ */
virtual NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, virtual NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) = 0; std::vector<u8>& output) = 0;
/** /**
@ -42,8 +44,8 @@ public:
* @param output A buffer where the output data will be written to. * @param output A buffer where the output data will be written to.
* @returns The result code of the ioctl. * @returns The result code of the ioctl.
*/ */
virtual NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, virtual NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) = 0; std::span<const u8> inline_input, std::vector<u8>& output) = 0;
/** /**
* Handles an ioctl3 request. * Handles an ioctl3 request.
@ -53,7 +55,7 @@ public:
* @param inline_output A buffer where the inlined output data will be written to. * @param inline_output A buffer where the inlined output data will be written to.
* @returns The result code of the ioctl. * @returns The result code of the ioctl.
*/ */
virtual NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, virtual NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) = 0; std::vector<u8>& output, std::vector<u8>& inline_output) = 0;
/** /**

View file

@ -17,19 +17,19 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system_, NvCore::Container& core)
: nvdevice{system_}, container{core}, nvmap{core.GetNvMapFile()} {} : nvdevice{system_}, container{core}, nvmap{core.GetNvMapFile()} {}
nvdisp_disp0::~nvdisp_disp0() = default; nvdisp_disp0::~nvdisp_disp0() = default;
NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvdisp_disp0::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvdisp_disp0::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvdisp_disp0::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvdisp_disp0::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) { std::vector<u8>& output, std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;

View file

@ -25,12 +25,12 @@ public:
explicit nvdisp_disp0(Core::System& system_, NvCore::Container& core); explicit nvdisp_disp0(Core::System& system_, NvCore::Container& core);
~nvdisp_disp0() override; ~nvdisp_disp0() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) override; std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) override; std::span<const u8> inline_input, std::vector<u8>& output) override;
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output) override; std::vector<u8>& inline_output) override;
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;

View file

@ -27,7 +27,7 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system_, Module& module_, NvCore::Con
nvhost_as_gpu::~nvhost_as_gpu() = default; nvhost_as_gpu::~nvhost_as_gpu() = default;
NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 'A': case 'A':
@ -60,13 +60,13 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_as_gpu::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_as_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) { std::vector<u8>& output, std::vector<u8>& inline_output) {
switch (command.group) { switch (command.group) {
case 'A': case 'A':
@ -87,7 +87,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>
void nvhost_as_gpu::OnOpen(DeviceFD fd) {} void nvhost_as_gpu::OnOpen(DeviceFD fd) {}
void nvhost_as_gpu::OnClose(DeviceFD fd) {} void nvhost_as_gpu::OnClose(DeviceFD fd) {}
NvResult nvhost_as_gpu::AllocAsEx(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::vector<u8>& output) {
IoctlAllocAsEx params{}; IoctlAllocAsEx params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
@ -141,7 +141,7 @@ NvResult nvhost_as_gpu::AllocAsEx(const std::vector<u8>& input, std::vector<u8>&
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::vector<u8>& output) {
IoctlAllocSpace params{}; IoctlAllocSpace params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
@ -220,7 +220,7 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) {
mapping_map.erase(offset); mapping_map.erase(offset);
} }
NvResult nvhost_as_gpu::FreeSpace(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::vector<u8>& output) {
IoctlFreeSpace params{}; IoctlFreeSpace params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
@ -266,7 +266,7 @@ NvResult nvhost_as_gpu::FreeSpace(const std::vector<u8>& input, std::vector<u8>&
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::vector<u8>& output) {
const auto num_entries = input.size() / sizeof(IoctlRemapEntry); const auto num_entries = input.size() / sizeof(IoctlRemapEntry);
LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries); LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries);
@ -320,7 +320,7 @@ NvResult nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& out
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::vector<u8>& output) {
IoctlMapBufferEx params{}; IoctlMapBufferEx params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
@ -424,7 +424,7 @@ NvResult nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::vector<u8>& output) {
IoctlUnmapBuffer params{}; IoctlUnmapBuffer params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
@ -463,7 +463,7 @@ NvResult nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_as_gpu::BindChannel(std::span<const u8> input, std::vector<u8>& output) {
IoctlBindChannel params{}; IoctlBindChannel params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd);
@ -492,7 +492,7 @@ void nvhost_as_gpu::GetVARegionsImpl(IoctlGetVaRegions& params) {
}; };
} }
NvResult nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::vector<u8>& output) {
IoctlGetVaRegions params{}; IoctlGetVaRegions params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
@ -511,7 +511,7 @@ NvResult nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& inline_output) { std::vector<u8>& inline_output) {
IoctlGetVaRegions params{}; IoctlGetVaRegions params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());

View file

@ -47,12 +47,12 @@ public:
explicit nvhost_as_gpu(Core::System& system_, Module& module, NvCore::Container& core); explicit nvhost_as_gpu(Core::System& system_, Module& module, NvCore::Container& core);
~nvhost_as_gpu() override; ~nvhost_as_gpu() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) override; std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) override; std::span<const u8> inline_input, std::vector<u8>& output) override;
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output) override; std::vector<u8>& inline_output) override;
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;
@ -138,17 +138,17 @@ private:
static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2, static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2,
"IoctlGetVaRegions is incorrect size"); "IoctlGetVaRegions is incorrect size");
NvResult AllocAsEx(const std::vector<u8>& input, std::vector<u8>& output); NvResult AllocAsEx(std::span<const u8> input, std::vector<u8>& output);
NvResult AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output); NvResult AllocateSpace(std::span<const u8> input, std::vector<u8>& output);
NvResult Remap(const std::vector<u8>& input, std::vector<u8>& output); NvResult Remap(std::span<const u8> input, std::vector<u8>& output);
NvResult MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); NvResult MapBufferEx(std::span<const u8> input, std::vector<u8>& output);
NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output); NvResult UnmapBuffer(std::span<const u8> input, std::vector<u8>& output);
NvResult FreeSpace(const std::vector<u8>& input, std::vector<u8>& output); NvResult FreeSpace(std::span<const u8> input, std::vector<u8>& output);
NvResult BindChannel(const std::vector<u8>& input, std::vector<u8>& output); NvResult BindChannel(std::span<const u8> input, std::vector<u8>& output);
void GetVARegionsImpl(IoctlGetVaRegions& params); void GetVARegionsImpl(IoctlGetVaRegions& params);
NvResult GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetVARegions(std::span<const u8> input, std::vector<u8>& output);
NvResult GetVARegions(const std::vector<u8>& input, std::vector<u8>& output, NvResult GetVARegions(std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& inline_output); std::vector<u8>& inline_output);
void FreeMappingLocked(u64 offset); void FreeMappingLocked(u64 offset);

View file

@ -34,7 +34,7 @@ nvhost_ctrl::~nvhost_ctrl() {
} }
} }
NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
@ -63,13 +63,13 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_ctrl::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_outpu) { std::vector<u8>& output, std::vector<u8>& inline_outpu) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
@ -79,7 +79,7 @@ void nvhost_ctrl::OnOpen(DeviceFD fd) {}
void nvhost_ctrl::OnClose(DeviceFD fd) {} void nvhost_ctrl::OnClose(DeviceFD fd) {}
NvResult nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl::NvOsGetConfigU32(std::span<const u8> input, std::vector<u8>& output) {
IocGetConfigParams params{}; IocGetConfigParams params{};
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(),
@ -87,7 +87,7 @@ NvResult nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector
return NvResult::ConfigVarNotFound; // Returns error on production mode return NvResult::ConfigVarNotFound; // Returns error on production mode
} }
NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_ctrl::IocCtrlEventWait(std::span<const u8> input, std::vector<u8>& output,
bool is_allocation) { bool is_allocation) {
IocCtrlEventWaitParams params{}; IocCtrlEventWaitParams params{};
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
@ -231,7 +231,7 @@ NvResult nvhost_ctrl::FreeEvent(u32 slot) {
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::vector<u8>& output) {
IocCtrlEventRegisterParams params{}; IocCtrlEventRegisterParams params{};
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
const u32 event_id = params.user_event_id; const u32 event_id = params.user_event_id;
@ -252,8 +252,7 @@ NvResult nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::ve
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl::IocCtrlEventUnregister(const std::vector<u8>& input, NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::vector<u8>& output) {
std::vector<u8>& output) {
IocCtrlEventUnregisterParams params{}; IocCtrlEventUnregisterParams params{};
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
const u32 event_id = params.user_event_id & 0x00FF; const u32 event_id = params.user_event_id & 0x00FF;
@ -263,7 +262,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(const std::vector<u8>& input,
return FreeEvent(event_id); return FreeEvent(event_id);
} }
NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(const std::vector<u8>& input, NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
IocCtrlEventUnregisterBatchParams params{}; IocCtrlEventUnregisterBatchParams params{};
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
@ -282,7 +281,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(const std::vector<u8>& input,
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl::IocCtrlClearEventWait(std::span<const u8> input, std::vector<u8>& output) {
IocCtrlEventClearParams params{}; IocCtrlEventClearParams params{};
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));

View file

@ -25,12 +25,12 @@ public:
NvCore::Container& core); NvCore::Container& core);
~nvhost_ctrl() override; ~nvhost_ctrl() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) override; std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) override; std::span<const u8> inline_input, std::vector<u8>& output) override;
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output) override; std::vector<u8>& inline_output) override;
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;
@ -186,13 +186,13 @@ private:
static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8,
"IocCtrlEventKill is incorrect size"); "IocCtrlEventKill is incorrect size");
NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output); NvResult NvOsGetConfigU32(std::span<const u8> input, std::vector<u8>& output);
NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, NvResult IocCtrlEventWait(std::span<const u8> input, std::vector<u8>& output,
bool is_allocation); bool is_allocation);
NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocCtrlEventRegister(std::span<const u8> input, std::vector<u8>& output);
NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocCtrlEventUnregister(std::span<const u8> input, std::vector<u8>& output);
NvResult IocCtrlEventUnregisterBatch(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocCtrlEventUnregisterBatch(std::span<const u8> input, std::vector<u8>& output);
NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocCtrlClearEventWait(std::span<const u8> input, std::vector<u8>& output);
NvResult FreeEvent(u32 slot); NvResult FreeEvent(u32 slot);

View file

@ -21,7 +21,7 @@ nvhost_ctrl_gpu::~nvhost_ctrl_gpu() {
events_interface.FreeEvent(unknown_event); events_interface.FreeEvent(unknown_event);
} }
NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 'G': case 'G':
@ -53,13 +53,13 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_ctrl_gpu::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) { std::vector<u8>& output, std::vector<u8>& inline_output) {
switch (command.group) { switch (command.group) {
case 'G': case 'G':
@ -82,8 +82,7 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u
void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {} void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {}
void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {}
NvResult nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vector<u8>& output) {
std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
IoctlCharacteristics params{}; IoctlCharacteristics params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
@ -128,7 +127,7 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input,
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& inline_output) { std::vector<u8>& inline_output) {
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
IoctlCharacteristics params{}; IoctlCharacteristics params{};
@ -176,7 +175,7 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8>& output) {
IoctlGpuGetTpcMasksArgs params{}; IoctlGpuGetTpcMasksArgs params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size);
@ -187,7 +186,7 @@ NvResult nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& inline_output) { std::vector<u8>& inline_output) {
IoctlGpuGetTpcMasksArgs params{}; IoctlGpuGetTpcMasksArgs params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
@ -200,7 +199,7 @@ NvResult nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span<const u8> input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
IoctlActiveSlotMask params{}; IoctlActiveSlotMask params{};
@ -213,7 +212,7 @@ NvResult nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::v
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span<const u8> input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
IoctlZcullGetCtxSize params{}; IoctlZcullGetCtxSize params{};
@ -225,7 +224,7 @@ NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vec
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
IoctlNvgpuGpuZcullGetInfoArgs params{}; IoctlNvgpuGpuZcullGetInfoArgs params{};
@ -248,7 +247,7 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span<const u8> input, std::vector<u8>& output) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called"); LOG_WARNING(Service_NVDRV, "(STUBBED) called");
IoctlZbcSetTable params{}; IoctlZbcSetTable params{};
@ -264,7 +263,7 @@ NvResult nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::ZBCQueryTable(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span<const u8> input, std::vector<u8>& output) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called"); LOG_WARNING(Service_NVDRV, "(STUBBED) called");
IoctlZbcQueryTable params{}; IoctlZbcQueryTable params{};
@ -274,7 +273,7 @@ NvResult nvhost_ctrl_gpu::ZBCQueryTable(const std::vector<u8>& input, std::vecto
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::FlushL2(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl_gpu::FlushL2(std::span<const u8> input, std::vector<u8>& output) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called"); LOG_WARNING(Service_NVDRV, "(STUBBED) called");
IoctlFlushL2 params{}; IoctlFlushL2 params{};
@ -284,7 +283,7 @@ NvResult nvhost_ctrl_gpu::FlushL2(const std::vector<u8>& input, std::vector<u8>&
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_ctrl_gpu::GetGpuTime(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl_gpu::GetGpuTime(std::span<const u8> input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
IoctlGetGpuTime params{}; IoctlGetGpuTime params{};

View file

@ -21,12 +21,12 @@ public:
explicit nvhost_ctrl_gpu(Core::System& system_, EventInterface& events_interface_); explicit nvhost_ctrl_gpu(Core::System& system_, EventInterface& events_interface_);
~nvhost_ctrl_gpu() override; ~nvhost_ctrl_gpu() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) override; std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) override; std::span<const u8> inline_input, std::vector<u8>& output) override;
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output) override; std::vector<u8>& inline_output) override;
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;
@ -151,21 +151,21 @@ private:
}; };
static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size");
NvResult GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetCharacteristics(std::span<const u8> input, std::vector<u8>& output);
NvResult GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output, NvResult GetCharacteristics(std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& inline_output); std::vector<u8>& inline_output);
NvResult GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetTPCMasks(std::span<const u8> input, std::vector<u8>& output);
NvResult GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output, NvResult GetTPCMasks(std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& inline_output); std::vector<u8>& inline_output);
NvResult GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetActiveSlotMask(std::span<const u8> input, std::vector<u8>& output);
NvResult ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output); NvResult ZCullGetCtxSize(std::span<const u8> input, std::vector<u8>& output);
NvResult ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output); NvResult ZCullGetInfo(std::span<const u8> input, std::vector<u8>& output);
NvResult ZBCSetTable(const std::vector<u8>& input, std::vector<u8>& output); NvResult ZBCSetTable(std::span<const u8> input, std::vector<u8>& output);
NvResult ZBCQueryTable(const std::vector<u8>& input, std::vector<u8>& output); NvResult ZBCQueryTable(std::span<const u8> input, std::vector<u8>& output);
NvResult FlushL2(const std::vector<u8>& input, std::vector<u8>& output); NvResult FlushL2(std::span<const u8> input, std::vector<u8>& output);
NvResult GetGpuTime(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetGpuTime(std::span<const u8> input, std::vector<u8>& output);
EventInterface& events_interface; EventInterface& events_interface;

View file

@ -46,7 +46,7 @@ nvhost_gpu::~nvhost_gpu() {
syncpoint_manager.FreeSyncpoint(channel_syncpoint); syncpoint_manager.FreeSyncpoint(channel_syncpoint);
} }
NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
@ -98,8 +98,8 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& i
return NvResult::NotImplemented; return NvResult::NotImplemented;
}; };
NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 'H': case 'H':
switch (command.cmd) { switch (command.cmd) {
@ -112,7 +112,7 @@ NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& i
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) { std::vector<u8>& output, std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
@ -121,7 +121,7 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& i
void nvhost_gpu::OnOpen(DeviceFD fd) {} void nvhost_gpu::OnOpen(DeviceFD fd) {}
void nvhost_gpu::OnClose(DeviceFD fd) {} void nvhost_gpu::OnClose(DeviceFD fd) {}
NvResult nvhost_gpu::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output) {
IoctlSetNvmapFD params{}; IoctlSetNvmapFD params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
@ -130,7 +130,7 @@ NvResult nvhost_gpu::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& o
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
IoctlClientData params{}; IoctlClientData params{};
@ -139,7 +139,7 @@ NvResult nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::vector<u8>& output) {
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
IoctlClientData params{}; IoctlClientData params{};
@ -149,7 +149,7 @@ NvResult nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::ZCullBind(std::span<const u8> input, std::vector<u8>& output) {
std::memcpy(&zcull_params, input.data(), input.size()); std::memcpy(&zcull_params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va,
zcull_params.mode); zcull_params.mode);
@ -158,7 +158,7 @@ NvResult nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& ou
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::SetErrorNotifier(std::span<const u8> input, std::vector<u8>& output) {
IoctlSetErrorNotifier params{}; IoctlSetErrorNotifier params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset, LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset,
@ -168,14 +168,14 @@ NvResult nvhost_gpu::SetErrorNotifier(const std::vector<u8>& input, std::vector<
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::SetChannelPriority(std::span<const u8> input, std::vector<u8>& output) {
std::memcpy(&channel_priority, input.data(), input.size()); std::memcpy(&channel_priority, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority);
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::vector<u8>& output) {
IoctlAllocGpfifoEx2 params{}; IoctlAllocGpfifoEx2 params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
LOG_WARNING(Service_NVDRV, LOG_WARNING(Service_NVDRV,
@ -197,7 +197,7 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::AllocateObjectContext(std::span<const u8> input, std::vector<u8>& output) {
IoctlAllocObjCtx params{}; IoctlAllocObjCtx params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num,
@ -293,7 +293,7 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::SubmitGPFIFOBase(const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8>& output,
bool kickoff) { bool kickoff) {
if (input.size() < sizeof(IoctlSubmitGpfifo)) { if (input.size() < sizeof(IoctlSubmitGpfifo)) {
UNIMPLEMENTED(); UNIMPLEMENTED();
@ -314,8 +314,7 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(const std::vector<u8>& input, std::vector<
return SubmitGPFIFOImpl(params, output, std::move(entries)); return SubmitGPFIFOImpl(params, output, std::move(entries));
} }
NvResult nvhost_gpu::SubmitGPFIFOBase(const std::vector<u8>& input, NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline,
const std::vector<u8>& input_inline,
std::vector<u8>& output) { std::vector<u8>& output) {
if (input.size() < sizeof(IoctlSubmitGpfifo)) { if (input.size() < sizeof(IoctlSubmitGpfifo)) {
UNIMPLEMENTED(); UNIMPLEMENTED();
@ -328,7 +327,7 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(const std::vector<u8>& input,
return SubmitGPFIFOImpl(params, output, std::move(entries)); return SubmitGPFIFOImpl(params, output, std::move(entries));
} }
NvResult nvhost_gpu::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::GetWaitbase(std::span<const u8> input, std::vector<u8>& output) {
IoctlGetWaitbase params{}; IoctlGetWaitbase params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase)); std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
@ -338,7 +337,7 @@ NvResult nvhost_gpu::GetWaitbase(const std::vector<u8>& input, std::vector<u8>&
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::ChannelSetTimeout(std::span<const u8> input, std::vector<u8>& output) {
IoctlChannelSetTimeout params{}; IoctlChannelSetTimeout params{};
std::memcpy(&params, input.data(), sizeof(IoctlChannelSetTimeout)); std::memcpy(&params, input.data(), sizeof(IoctlChannelSetTimeout));
LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout); LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout);
@ -346,7 +345,7 @@ NvResult nvhost_gpu::ChannelSetTimeout(const std::vector<u8>& input, std::vector
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_gpu::ChannelSetTimeslice(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_gpu::ChannelSetTimeslice(std::span<const u8> input, std::vector<u8>& output) {
IoctlSetTimeslice params{}; IoctlSetTimeslice params{};
std::memcpy(&params, input.data(), sizeof(IoctlSetTimeslice)); std::memcpy(&params, input.data(), sizeof(IoctlSetTimeslice));
LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice); LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice);

View file

@ -40,12 +40,12 @@ public:
NvCore::Container& core); NvCore::Container& core);
~nvhost_gpu() override; ~nvhost_gpu() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) override; std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) override; std::span<const u8> inline_input, std::vector<u8>& output) override;
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output) override; std::vector<u8>& inline_output) override;
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;
@ -186,23 +186,23 @@ private:
u32_le channel_priority{}; u32_le channel_priority{};
u32_le channel_timeslice{}; u32_le channel_timeslice{};
NvResult SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); NvResult SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output);
NvResult SetClientData(const std::vector<u8>& input, std::vector<u8>& output); NvResult SetClientData(std::span<const u8> input, std::vector<u8>& output);
NvResult GetClientData(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetClientData(std::span<const u8> input, std::vector<u8>& output);
NvResult ZCullBind(const std::vector<u8>& input, std::vector<u8>& output); NvResult ZCullBind(std::span<const u8> input, std::vector<u8>& output);
NvResult SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output); NvResult SetErrorNotifier(std::span<const u8> input, std::vector<u8>& output);
NvResult SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output); NvResult SetChannelPriority(std::span<const u8> input, std::vector<u8>& output);
NvResult AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output); NvResult AllocGPFIFOEx2(std::span<const u8> input, std::vector<u8>& output);
NvResult AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output); NvResult AllocateObjectContext(std::span<const u8> input, std::vector<u8>& output);
NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>& output, NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>& output,
Tegra::CommandList&& entries); Tegra::CommandList&& entries);
NvResult SubmitGPFIFOBase(const std::vector<u8>& input, std::vector<u8>& output, NvResult SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8>& output,
bool kickoff = false); bool kickoff = false);
NvResult SubmitGPFIFOBase(const std::vector<u8>& input, const std::vector<u8>& input_inline, NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline,
std::vector<u8>& output); std::vector<u8>& output);
NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetWaitbase(std::span<const u8> input, std::vector<u8>& output);
NvResult ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output); NvResult ChannelSetTimeout(std::span<const u8> input, std::vector<u8>& output);
NvResult ChannelSetTimeslice(const std::vector<u8>& input, std::vector<u8>& output); NvResult ChannelSetTimeslice(std::span<const u8> input, std::vector<u8>& output);
EventInterface& events_interface; EventInterface& events_interface;
NvCore::Container& core; NvCore::Container& core;

View file

@ -15,7 +15,7 @@ nvhost_nvdec::nvhost_nvdec(Core::System& system_, NvCore::Container& core_)
: nvhost_nvdec_common{system_, core_, NvCore::ChannelType::NvDec} {} : nvhost_nvdec_common{system_, core_, NvCore::ChannelType::NvDec} {}
nvhost_nvdec::~nvhost_nvdec() = default; nvhost_nvdec::~nvhost_nvdec() = default;
NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
@ -55,13 +55,13 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_nvdec::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_nvdec::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) { std::vector<u8>& output, std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;

View file

@ -13,12 +13,12 @@ public:
explicit nvhost_nvdec(Core::System& system_, NvCore::Container& core); explicit nvhost_nvdec(Core::System& system_, NvCore::Container& core);
~nvhost_nvdec() override; ~nvhost_nvdec() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) override; std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) override; std::span<const u8> inline_input, std::vector<u8>& output) override;
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output) override; std::vector<u8>& inline_output) override;
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;

View file

@ -23,7 +23,7 @@ namespace {
// Copies count amount of type T from the input vector into the dst vector. // Copies count amount of type T from the input vector into the dst vector.
// Returns the number of bytes written into dst. // Returns the number of bytes written into dst.
template <typename T> template <typename T>
std::size_t SliceVectors(const std::vector<u8>& input, std::vector<T>& dst, std::size_t count, std::size_t SliceVectors(std::span<const u8> input, std::vector<T>& dst, std::size_t count,
std::size_t offset) { std::size_t offset) {
if (dst.empty()) { if (dst.empty()) {
return 0; return 0;
@ -63,7 +63,7 @@ nvhost_nvdec_common::~nvhost_nvdec_common() {
core.Host1xDeviceFile().syncpts_accumulated.push_back(channel_syncpoint); core.Host1xDeviceFile().syncpts_accumulated.push_back(channel_syncpoint);
} }
NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector<u8>& input) { NvResult nvhost_nvdec_common::SetNVMAPfd(std::span<const u8> input) {
IoctlSetNvmapFD params{}; IoctlSetNvmapFD params{};
std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD)); std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
@ -72,7 +72,7 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector<u8>& input) {
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_nvdec_common::Submit(DeviceFD fd, const std::vector<u8>& input, NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
IoctlSubmit params{}; IoctlSubmit params{};
std::memcpy(&params, input.data(), sizeof(IoctlSubmit)); std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
@ -121,7 +121,7 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, const std::vector<u8>& input,
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_nvdec_common::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::vector<u8>& output) {
IoctlGetSyncpoint params{}; IoctlGetSyncpoint params{};
std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint)); std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param);
@ -133,7 +133,7 @@ NvResult nvhost_nvdec_common::GetSyncpoint(const std::vector<u8>& input, std::ve
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_nvdec_common::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::vector<u8>& output) {
IoctlGetWaitbase params{}; IoctlGetWaitbase params{};
LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); LOG_CRITICAL(Service_NVDRV, "called WAITBASE");
std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase)); std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
@ -142,7 +142,7 @@ NvResult nvhost_nvdec_common::GetWaitbase(const std::vector<u8>& input, std::vec
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_nvdec_common::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::vector<u8>& output) {
IoctlMapBuffer params{}; IoctlMapBuffer params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer)); std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
@ -159,7 +159,7 @@ NvResult nvhost_nvdec_common::MapBuffer(const std::vector<u8>& input, std::vecto
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_nvdec_common::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::vector<u8>& output) {
IoctlMapBuffer params{}; IoctlMapBuffer params{};
std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer)); std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
@ -173,8 +173,7 @@ NvResult nvhost_nvdec_common::UnmapBuffer(const std::vector<u8>& input, std::vec
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_nvdec_common::SetSubmitTimeout(const std::vector<u8>& input, NvResult nvhost_nvdec_common::SetSubmitTimeout(std::span<const u8> input, std::vector<u8>& output) {
std::vector<u8>& output) {
std::memcpy(&submit_timeout, input.data(), input.size()); std::memcpy(&submit_timeout, input.data(), input.size());
LOG_WARNING(Service_NVDRV, "(STUBBED) called"); LOG_WARNING(Service_NVDRV, "(STUBBED) called");
return NvResult::Success; return NvResult::Success;

View file

@ -107,13 +107,13 @@ protected:
static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size"); static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size");
/// Ioctl command implementations /// Ioctl command implementations
NvResult SetNVMAPfd(const std::vector<u8>& input); NvResult SetNVMAPfd(std::span<const u8> input);
NvResult Submit(DeviceFD fd, const std::vector<u8>& input, std::vector<u8>& output); NvResult Submit(DeviceFD fd, std::span<const u8> input, std::vector<u8>& output);
NvResult GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetSyncpoint(std::span<const u8> input, std::vector<u8>& output);
NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetWaitbase(std::span<const u8> input, std::vector<u8>& output);
NvResult MapBuffer(const std::vector<u8>& input, std::vector<u8>& output); NvResult MapBuffer(std::span<const u8> input, std::vector<u8>& output);
NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output); NvResult UnmapBuffer(std::span<const u8> input, std::vector<u8>& output);
NvResult SetSubmitTimeout(const std::vector<u8>& input, std::vector<u8>& output); NvResult SetSubmitTimeout(std::span<const u8> input, std::vector<u8>& output);
Kernel::KEvent* QueryEvent(u32 event_id) override; Kernel::KEvent* QueryEvent(u32 event_id) override;

View file

@ -12,7 +12,7 @@ namespace Service::Nvidia::Devices {
nvhost_nvjpg::nvhost_nvjpg(Core::System& system_) : nvdevice{system_} {} nvhost_nvjpg::nvhost_nvjpg(Core::System& system_) : nvdevice{system_} {}
nvhost_nvjpg::~nvhost_nvjpg() = default; nvhost_nvjpg::~nvhost_nvjpg() = default;
NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 'H': case 'H':
@ -31,13 +31,13 @@ NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_nvjpg::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_nvjpg::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) { std::vector<u8>& output, std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
@ -46,7 +46,7 @@ NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>&
void nvhost_nvjpg::OnOpen(DeviceFD fd) {} void nvhost_nvjpg::OnOpen(DeviceFD fd) {}
void nvhost_nvjpg::OnClose(DeviceFD fd) {} void nvhost_nvjpg::OnClose(DeviceFD fd) {}
NvResult nvhost_nvjpg::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_nvjpg::SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output) {
IoctlSetNvmapFD params{}; IoctlSetNvmapFD params{};
std::memcpy(&params, input.data(), input.size()); std::memcpy(&params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);

View file

@ -15,12 +15,12 @@ public:
explicit nvhost_nvjpg(Core::System& system_); explicit nvhost_nvjpg(Core::System& system_);
~nvhost_nvjpg() override; ~nvhost_nvjpg() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) override; std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) override; std::span<const u8> inline_input, std::vector<u8>& output) override;
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output) override; std::vector<u8>& inline_output) override;
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;
@ -33,7 +33,7 @@ private:
s32_le nvmap_fd{}; s32_le nvmap_fd{};
NvResult SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); NvResult SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output);
}; };
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

View file

@ -15,7 +15,7 @@ nvhost_vic::nvhost_vic(Core::System& system_, NvCore::Container& core_)
nvhost_vic::~nvhost_vic() = default; nvhost_vic::~nvhost_vic() = default;
NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
@ -55,13 +55,13 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& i
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_vic::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_vic::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) { std::vector<u8>& output, std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;

View file

@ -12,12 +12,12 @@ public:
explicit nvhost_vic(Core::System& system_, NvCore::Container& core); explicit nvhost_vic(Core::System& system_, NvCore::Container& core);
~nvhost_vic(); ~nvhost_vic();
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) override; std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) override; std::span<const u8> inline_input, std::vector<u8>& output) override;
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output) override; std::vector<u8>& inline_output) override;
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;

View file

@ -25,7 +25,7 @@ nvmap::nvmap(Core::System& system_, NvCore::Container& container_)
nvmap::~nvmap() = default; nvmap::~nvmap() = default;
NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 0x1: case 0x1:
@ -54,13 +54,13 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvmap::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvmap::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) { std::vector<u8>& output, std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
@ -69,7 +69,7 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
void nvmap::OnOpen(DeviceFD fd) {} void nvmap::OnOpen(DeviceFD fd) {}
void nvmap::OnClose(DeviceFD fd) {} void nvmap::OnClose(DeviceFD fd) {}
NvResult nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvmap::IocCreate(std::span<const u8> input, std::vector<u8>& output) {
IocCreateParams params; IocCreateParams params;
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size);
@ -89,7 +89,7 @@ NvResult nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output)
return NvResult::Success; return NvResult::Success;
} }
NvResult nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvmap::IocAlloc(std::span<const u8> input, std::vector<u8>& output) {
IocAllocParams params; IocAllocParams params;
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address);
@ -137,7 +137,7 @@ NvResult nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output)
return result; return result;
} }
NvResult nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvmap::IocGetId(std::span<const u8> input, std::vector<u8>& output) {
IocGetIdParams params; IocGetIdParams params;
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
@ -161,7 +161,7 @@ NvResult nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output)
return NvResult::Success; return NvResult::Success;
} }
NvResult nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvmap::IocFromId(std::span<const u8> input, std::vector<u8>& output) {
IocFromIdParams params; IocFromIdParams params;
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
@ -192,7 +192,7 @@ NvResult nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output)
return NvResult::Success; return NvResult::Success;
} }
NvResult nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvmap::IocParam(std::span<const u8> input, std::vector<u8>& output) {
enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 };
IocParamParams params; IocParamParams params;
@ -241,7 +241,7 @@ NvResult nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output)
return NvResult::Success; return NvResult::Success;
} }
NvResult nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvmap::IocFree(std::span<const u8> input, std::vector<u8>& output) {
IocFreeParams params; IocFreeParams params;
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));

View file

@ -26,12 +26,12 @@ public:
nvmap(const nvmap&) = delete; nvmap(const nvmap&) = delete;
nvmap& operator=(const nvmap&) = delete; nvmap& operator=(const nvmap&) = delete;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) override; std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) override; std::span<const u8> inline_input, std::vector<u8>& output) override;
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output) override; std::vector<u8>& inline_output) override;
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;
@ -106,12 +106,12 @@ private:
}; };
static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size");
NvResult IocCreate(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocCreate(std::span<const u8> input, std::vector<u8>& output);
NvResult IocAlloc(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocAlloc(std::span<const u8> input, std::vector<u8>& output);
NvResult IocGetId(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocGetId(std::span<const u8> input, std::vector<u8>& output);
NvResult IocFromId(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocFromId(std::span<const u8> input, std::vector<u8>& output);
NvResult IocParam(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocParam(std::span<const u8> input, std::vector<u8>& output);
NvResult IocFree(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocFree(std::span<const u8> input, std::vector<u8>& output);
NvCore::Container& container; NvCore::Container& container;
NvCore::NvMap& file; NvCore::NvMap& file;

View file

@ -124,7 +124,7 @@ DeviceFD Module::Open(const std::string& device_name) {
return fd; return fd;
} }
NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output) { std::vector<u8>& output) {
if (fd < 0) { if (fd < 0) {
LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
@ -141,8 +141,8 @@ NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input
return itr->second->Ioctl1(fd, command, input, output); return itr->second->Ioctl1(fd, command, input, output);
} }
NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output) { std::span<const u8> inline_input, std::vector<u8>& output) {
if (fd < 0) { if (fd < 0) {
LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
return NvResult::InvalidState; return NvResult::InvalidState;
@ -158,7 +158,7 @@ NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input
return itr->second->Ioctl2(fd, command, input, inline_input, output); return itr->second->Ioctl2(fd, command, input, inline_input, output);
} }
NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
std::vector<u8>& output, std::vector<u8>& inline_output) { std::vector<u8>& output, std::vector<u8>& inline_output) {
if (fd < 0) { if (fd < 0) {
LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);

View file

@ -7,6 +7,7 @@
#include <functional> #include <functional>
#include <list> #include <list>
#include <memory> #include <memory>
#include <span>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@ -79,14 +80,13 @@ public:
DeviceFD Open(const std::string& device_name); DeviceFD Open(const std::string& device_name);
/// Sends an ioctl command to the specified file descriptor. /// Sends an ioctl command to the specified file descriptor.
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output);
std::vector<u8>& output);
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
const std::vector<u8>& inline_input, std::vector<u8>& output); std::span<const u8> inline_input, std::vector<u8>& output);
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output,
std::vector<u8>& output, std::vector<u8>& inline_output); std::vector<u8>& inline_output);
/// Closes a device file descriptor and returns operation success. /// Closes a device file descriptor and returns operation success.
NvResult Close(DeviceFD fd); NvResult Close(DeviceFD fd);

View file

@ -815,8 +815,8 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
void BufferQueueProducer::Transact(Kernel::HLERequestContext& ctx, TransactionId code, u32 flags) { void BufferQueueProducer::Transact(Kernel::HLERequestContext& ctx, TransactionId code, u32 flags) {
Status status{Status::NoError}; Status status{Status::NoError};
Parcel parcel_in{ctx.ReadBuffer()}; InputParcel parcel_in{ctx.ReadBuffer()};
Parcel parcel_out{}; OutputParcel parcel_out{};
switch (code) { switch (code) {
case TransactionId::Connect: { case TransactionId::Connect: {

View file

@ -9,7 +9,7 @@
namespace Service::android { namespace Service::android {
QueueBufferInput::QueueBufferInput(Parcel& parcel) { QueueBufferInput::QueueBufferInput(InputParcel& parcel) {
parcel.ReadFlattened(*this); parcel.ReadFlattened(*this);
} }

View file

@ -14,11 +14,11 @@
namespace Service::android { namespace Service::android {
class Parcel; class InputParcel;
#pragma pack(push, 1) #pragma pack(push, 1)
struct QueueBufferInput final { struct QueueBufferInput final {
explicit QueueBufferInput(Parcel& parcel); explicit QueueBufferInput(InputParcel& parcel);
void Deflate(s64* timestamp_, bool* is_auto_timestamp_, Common::Rectangle<s32>* crop_, void Deflate(s64* timestamp_, bool* is_auto_timestamp_, Common::Rectangle<s32>* crop_,
NativeWindowScalingMode* scaling_mode_, NativeWindowTransform* transform_, NativeWindowScalingMode* scaling_mode_, NativeWindowTransform* transform_,

View file

@ -312,8 +312,6 @@ void NVFlinger::Compose() {
} }
s64 NVFlinger::GetNextTicks() const { s64 NVFlinger::GetNextTicks() const {
static constexpr s64 max_hertz = 120LL;
const auto& settings = Settings::values; const auto& settings = Settings::values;
auto speed_scale = 1.f; auto speed_scale = 1.f;
if (settings.use_multi_core.GetValue()) { if (settings.use_multi_core.GetValue()) {
@ -327,9 +325,11 @@ s64 NVFlinger::GetNextTicks() const {
} }
} }
const auto next_ticks = ((1000000000 * (1LL << swap_interval)) / max_hertz); // As an extension, treat nonpositive swap interval as framerate multiplier.
const f32 effective_fps = swap_interval <= 0 ? 120.f * static_cast<f32>(1 - swap_interval)
: 60.f / static_cast<f32>(swap_interval);
return static_cast<s64>(speed_scale * static_cast<float>(next_ticks)); return static_cast<s64>(speed_scale * (1000000000.f / effective_fps));
} }
} // namespace Service::NVFlinger } // namespace Service::NVFlinger

View file

@ -133,7 +133,7 @@ private:
/// layers. /// layers.
u32 next_buffer_queue_id = 1; u32 next_buffer_queue_id = 1;
u32 swap_interval = 1; s32 swap_interval = 1;
/// Event that handles screen composition. /// Event that handles screen composition.
std::shared_ptr<Core::Timing::EventType> multi_composition_event; std::shared_ptr<Core::Timing::EventType> multi_composition_event;

View file

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <span>
#include <vector> #include <vector>
#include "common/alignment.h" #include "common/alignment.h"
@ -12,18 +13,17 @@
namespace Service::android { namespace Service::android {
class Parcel final { struct ParcelHeader {
u32 data_size;
u32 data_offset;
u32 objects_size;
u32 objects_offset;
};
static_assert(sizeof(ParcelHeader) == 16, "ParcelHeader has wrong size");
class InputParcel final {
public: public:
static constexpr std::size_t DefaultBufferSize = 0x40; explicit InputParcel(std::span<const u8> in_data) : read_buffer(std::move(in_data)) {
Parcel() : buffer(DefaultBufferSize) {}
template <typename T>
explicit Parcel(const T& out_data) : buffer(DefaultBufferSize) {
Write(out_data);
}
explicit Parcel(std::vector<u8> in_data) : buffer(std::move(in_data)) {
DeserializeHeader(); DeserializeHeader();
[[maybe_unused]] const std::u16string token = ReadInterfaceToken(); [[maybe_unused]] const std::u16string token = ReadInterfaceToken();
} }
@ -31,9 +31,9 @@ public:
template <typename T> template <typename T>
void Read(T& val) { void Read(T& val) {
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
ASSERT(read_index + sizeof(T) <= buffer.size()); ASSERT(read_index + sizeof(T) <= read_buffer.size());
std::memcpy(&val, buffer.data() + read_index, sizeof(T)); std::memcpy(&val, read_buffer.data() + read_index, sizeof(T));
read_index += sizeof(T); read_index += sizeof(T);
read_index = Common::AlignUp(read_index, 4); read_index = Common::AlignUp(read_index, 4);
} }
@ -62,10 +62,10 @@ public:
template <typename T> template <typename T>
T ReadUnaligned() { T ReadUnaligned() {
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
ASSERT(read_index + sizeof(T) <= buffer.size()); ASSERT(read_index + sizeof(T) <= read_buffer.size());
T val; T val;
std::memcpy(&val, buffer.data() + read_index, sizeof(T)); std::memcpy(&val, read_buffer.data() + read_index, sizeof(T));
read_index += sizeof(T); read_index += sizeof(T);
return val; return val;
} }
@ -101,6 +101,31 @@ public:
return token; return token;
} }
void DeserializeHeader() {
ASSERT(read_buffer.size() > sizeof(ParcelHeader));
ParcelHeader header{};
std::memcpy(&header, read_buffer.data(), sizeof(ParcelHeader));
read_index = header.data_offset;
}
private:
std::span<const u8> read_buffer;
std::size_t read_index = 0;
};
class OutputParcel final {
public:
static constexpr std::size_t DefaultBufferSize = 0x40;
OutputParcel() : buffer(DefaultBufferSize) {}
template <typename T>
explicit OutputParcel(const T& out_data) : buffer(DefaultBufferSize) {
Write(out_data);
}
template <typename T> template <typename T>
void Write(const T& val) { void Write(const T& val) {
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
@ -133,40 +158,20 @@ public:
WriteObject(ptr.get()); WriteObject(ptr.get());
} }
void DeserializeHeader() {
ASSERT(buffer.size() > sizeof(Header));
Header header{};
std::memcpy(&header, buffer.data(), sizeof(Header));
read_index = header.data_offset;
}
std::vector<u8> Serialize() const { std::vector<u8> Serialize() const {
ASSERT(read_index == 0); ParcelHeader header{};
header.data_size = static_cast<u32>(write_index - sizeof(ParcelHeader));
Header header{}; header.data_offset = sizeof(ParcelHeader);
header.data_size = static_cast<u32>(write_index - sizeof(Header));
header.data_offset = sizeof(Header);
header.objects_size = 4; header.objects_size = 4;
header.objects_offset = static_cast<u32>(sizeof(Header) + header.data_size); header.objects_offset = static_cast<u32>(sizeof(ParcelHeader) + header.data_size);
std::memcpy(buffer.data(), &header, sizeof(Header)); std::memcpy(buffer.data(), &header, sizeof(ParcelHeader));
return buffer; return buffer;
} }
private: private:
struct Header {
u32 data_size;
u32 data_offset;
u32 objects_size;
u32 objects_offset;
};
static_assert(sizeof(Header) == 16, "ParcelHeader has wrong size");
mutable std::vector<u8> buffer; mutable std::vector<u8> buffer;
std::size_t read_index = 0; std::size_t write_index = sizeof(ParcelHeader);
std::size_t write_index = sizeof(Header);
}; };
} // namespace Service::android } // namespace Service::android

View file

@ -63,7 +63,7 @@ private:
return ctx.ReadBuffer(1); return ctx.ReadBuffer(1);
} }
return std::vector<u8>{}; return std::span<const u8>{};
}(); }();
LOG_DEBUG(Service_PREPO, LOG_DEBUG(Service_PREPO,
@ -90,7 +90,7 @@ private:
return ctx.ReadBuffer(1); return ctx.ReadBuffer(1);
} }
return std::vector<u8>{}; return std::span<const u8>{};
}(); }();
LOG_DEBUG(Service_PREPO, LOG_DEBUG(Service_PREPO,
@ -142,7 +142,7 @@ private:
return ctx.ReadBuffer(1); return ctx.ReadBuffer(1);
} }
return std::vector<u8>{}; return std::span<const u8>{};
}(); }();
LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}", LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}",
@ -166,7 +166,7 @@ private:
return ctx.ReadBuffer(1); return ctx.ReadBuffer(1);
} }
return std::vector<u8>{}; return std::span<const u8>{};
}(); }();
LOG_DEBUG(Service_PREPO, LOG_DEBUG(Service_PREPO,

View file

@ -208,7 +208,6 @@ void BSD::Bind(Kernel::HLERequestContext& ctx) {
const s32 fd = rp.Pop<s32>(); const s32 fd = rp.Pop<s32>();
LOG_DEBUG(Service, "called. fd={} addrlen={}", fd, ctx.GetReadBufferSize()); LOG_DEBUG(Service, "called. fd={} addrlen={}", fd, ctx.GetReadBufferSize());
BuildErrnoResponse(ctx, BindImpl(fd, ctx.ReadBuffer())); BuildErrnoResponse(ctx, BindImpl(fd, ctx.ReadBuffer()));
} }
@ -312,7 +311,7 @@ void BSD::SetSockOpt(Kernel::HLERequestContext& ctx) {
const u32 level = rp.Pop<u32>(); const u32 level = rp.Pop<u32>();
const OptName optname = static_cast<OptName>(rp.Pop<u32>()); const OptName optname = static_cast<OptName>(rp.Pop<u32>());
const std::vector<u8> buffer = ctx.ReadBuffer(); const auto buffer = ctx.ReadBuffer();
const u8* optval = buffer.empty() ? nullptr : buffer.data(); const u8* optval = buffer.empty() ? nullptr : buffer.data();
size_t optlen = buffer.size(); size_t optlen = buffer.size();
@ -489,7 +488,7 @@ std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protoco
return {fd, Errno::SUCCESS}; return {fd, Errno::SUCCESS};
} }
std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::vector<u8> read_buffer, std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
s32 nfds, s32 timeout) { s32 nfds, s32 timeout) {
if (write_buffer.size() < nfds * sizeof(PollFD)) { if (write_buffer.size() < nfds * sizeof(PollFD)) {
return {-1, Errno::INVAL}; return {-1, Errno::INVAL};
@ -584,7 +583,7 @@ std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
return {new_fd, Errno::SUCCESS}; return {new_fd, Errno::SUCCESS};
} }
Errno BSD::BindImpl(s32 fd, const std::vector<u8>& addr) { Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
if (!IsFileDescriptorValid(fd)) { if (!IsFileDescriptorValid(fd)) {
return Errno::BADF; return Errno::BADF;
} }
@ -595,7 +594,7 @@ Errno BSD::BindImpl(s32 fd, const std::vector<u8>& addr) {
return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
} }
Errno BSD::ConnectImpl(s32 fd, const std::vector<u8>& addr) { Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
if (!IsFileDescriptorValid(fd)) { if (!IsFileDescriptorValid(fd)) {
return Errno::BADF; return Errno::BADF;
} }
@ -800,15 +799,15 @@ std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& mess
return {ret, bsd_errno}; return {ret, bsd_errno};
} }
std::pair<s32, Errno> BSD::SendImpl(s32 fd, u32 flags, const std::vector<u8>& message) { std::pair<s32, Errno> BSD::SendImpl(s32 fd, u32 flags, std::span<const u8> message) {
if (!IsFileDescriptorValid(fd)) { if (!IsFileDescriptorValid(fd)) {
return {-1, Errno::BADF}; return {-1, Errno::BADF};
} }
return Translate(file_descriptors[fd]->socket->Send(message, flags)); return Translate(file_descriptors[fd]->socket->Send(message, flags));
} }
std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, const std::vector<u8>& message, std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
const std::vector<u8>& addr) { std::span<const u8> addr) {
if (!IsFileDescriptorValid(fd)) { if (!IsFileDescriptorValid(fd)) {
return {-1, Errno::BADF}; return {-1, Errno::BADF};
} }

View file

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <span>
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
@ -44,7 +45,7 @@ private:
s32 nfds; s32 nfds;
s32 timeout; s32 timeout;
std::vector<u8> read_buffer; std::span<const u8> read_buffer;
std::vector<u8> write_buffer; std::vector<u8> write_buffer;
s32 ret{}; s32 ret{};
Errno bsd_errno{}; Errno bsd_errno{};
@ -65,7 +66,7 @@ private:
void Response(Kernel::HLERequestContext& ctx); void Response(Kernel::HLERequestContext& ctx);
s32 fd; s32 fd;
std::vector<u8> addr; std::span<const u8> addr;
Errno bsd_errno{}; Errno bsd_errno{};
}; };
@ -98,7 +99,7 @@ private:
s32 fd; s32 fd;
u32 flags; u32 flags;
std::vector<u8> message; std::span<const u8> message;
s32 ret{}; s32 ret{};
Errno bsd_errno{}; Errno bsd_errno{};
}; };
@ -109,8 +110,8 @@ private:
s32 fd; s32 fd;
u32 flags; u32 flags;
std::vector<u8> message; std::span<const u8> message;
std::vector<u8> addr; std::span<const u8> addr;
s32 ret{}; s32 ret{};
Errno bsd_errno{}; Errno bsd_errno{};
}; };
@ -143,11 +144,11 @@ private:
void ExecuteWork(Kernel::HLERequestContext& ctx, Work work); void ExecuteWork(Kernel::HLERequestContext& ctx, Work work);
std::pair<s32, Errno> SocketImpl(Domain domain, Type type, Protocol protocol); std::pair<s32, Errno> SocketImpl(Domain domain, Type type, Protocol protocol);
std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::vector<u8> read_buffer, std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
s32 nfds, s32 timeout); s32 nfds, s32 timeout);
std::pair<s32, Errno> AcceptImpl(s32 fd, std::vector<u8>& write_buffer); std::pair<s32, Errno> AcceptImpl(s32 fd, std::vector<u8>& write_buffer);
Errno BindImpl(s32 fd, const std::vector<u8>& addr); Errno BindImpl(s32 fd, std::span<const u8> addr);
Errno ConnectImpl(s32 fd, const std::vector<u8>& addr); Errno ConnectImpl(s32 fd, std::span<const u8> addr);
Errno GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer); Errno GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer);
Errno GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer); Errno GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer);
Errno ListenImpl(s32 fd, s32 backlog); Errno ListenImpl(s32 fd, s32 backlog);
@ -157,9 +158,9 @@ private:
std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message); std::pair<s32, Errno> RecvImpl(s32 fd, u32 flags, std::vector<u8>& message);
std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message, std::pair<s32, Errno> RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
std::vector<u8>& addr); std::vector<u8>& addr);
std::pair<s32, Errno> SendImpl(s32 fd, u32 flags, const std::vector<u8>& message); std::pair<s32, Errno> SendImpl(s32 fd, u32 flags, std::span<const u8> message);
std::pair<s32, Errno> SendToImpl(s32 fd, u32 flags, const std::vector<u8>& message, std::pair<s32, Errno> SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
const std::vector<u8>& addr); std::span<const u8> addr);
Errno CloseImpl(s32 fd); Errno CloseImpl(s32 fd);
s32 FindFreeFileDescriptorHandle() noexcept; s32 FindFreeFileDescriptorHandle() noexcept;

View file

@ -101,7 +101,7 @@ private:
void ImportServerPki(Kernel::HLERequestContext& ctx) { void ImportServerPki(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const auto certificate_format = rp.PopEnum<CertificateFormat>(); const auto certificate_format = rp.PopEnum<CertificateFormat>();
const auto pkcs_12_certificates = ctx.ReadBuffer(0); [[maybe_unused]] const auto pkcs_12_certificates = ctx.ReadBuffer(0);
constexpr u64 server_id = 0; constexpr u64 server_id = 0;
@ -113,13 +113,13 @@ private:
} }
void ImportClientPki(Kernel::HLERequestContext& ctx) { void ImportClientPki(Kernel::HLERequestContext& ctx) {
const auto pkcs_12_certificate = ctx.ReadBuffer(0); [[maybe_unused]] const auto pkcs_12_certificate = ctx.ReadBuffer(0);
const auto ascii_password = [&ctx] { [[maybe_unused]] const auto ascii_password = [&ctx] {
if (ctx.CanReadBuffer(1)) { if (ctx.CanReadBuffer(1)) {
return ctx.ReadBuffer(1); return ctx.ReadBuffer(1);
} }
return std::vector<u8>{}; return std::span<const u8>{};
}(); }();
constexpr u64 client_id = 0; constexpr u64 client_id = 0;

View file

@ -603,7 +603,7 @@ private:
return; return;
} }
const auto parcel = android::Parcel{NativeWindow{*buffer_queue_id}}; const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}};
const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
IPC::ResponseBuilder rb{ctx, 4}; IPC::ResponseBuilder rb{ctx, 4};
@ -649,7 +649,7 @@ private:
return; return;
} }
const auto parcel = android::Parcel{NativeWindow{*buffer_queue_id}}; const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}};
const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
IPC::ResponseBuilder rb{ctx, 6}; IPC::ResponseBuilder rb{ctx, 6};

View file

@ -550,7 +550,7 @@ std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, Sock
return {-1, GetAndLogLastError()}; return {-1, GetAndLogLastError()};
} }
std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) { std::pair<s32, Errno> Socket::Send(std::span<const u8> message, int flags) {
ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
ASSERT(flags == 0); ASSERT(flags == 0);
@ -563,7 +563,7 @@ std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) {
return {-1, GetAndLogLastError()}; return {-1, GetAndLogLastError()};
} }
std::pair<s32, Errno> Socket::SendTo(u32 flags, const std::vector<u8>& message, std::pair<s32, Errno> Socket::SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) { const SockAddrIn* addr) {
ASSERT(flags == 0); ASSERT(flags == 0);

View file

@ -182,7 +182,7 @@ std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::vector<u8>& mes
return {static_cast<u32>(read_bytes), Errno::SUCCESS}; return {static_cast<u32>(read_bytes), Errno::SUCCESS};
} }
std::pair<s32, Errno> ProxySocket::Send(const std::vector<u8>& message, int flags) { std::pair<s32, Errno> ProxySocket::Send(std::span<const u8> message, int flags) {
LOG_WARNING(Network, "(STUBBED) called"); LOG_WARNING(Network, "(STUBBED) called");
ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
ASSERT(flags == 0); ASSERT(flags == 0);
@ -200,7 +200,7 @@ void ProxySocket::SendPacket(ProxyPacket& packet) {
} }
} }
std::pair<s32, Errno> ProxySocket::SendTo(u32 flags, const std::vector<u8>& message, std::pair<s32, Errno> ProxySocket::SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) { const SockAddrIn* addr) {
ASSERT(flags == 0); ASSERT(flags == 0);

View file

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <mutex> #include <mutex>
#include <span>
#include <vector> #include <vector>
#include <queue> #include <queue>
@ -48,11 +49,11 @@ public:
std::pair<s32, Errno> ReceivePacket(int flags, std::vector<u8>& message, SockAddrIn* addr, std::pair<s32, Errno> ReceivePacket(int flags, std::vector<u8>& message, SockAddrIn* addr,
std::size_t max_length); std::size_t max_length);
std::pair<s32, Errno> Send(const std::vector<u8>& message, int flags) override; std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
void SendPacket(ProxyPacket& packet); void SendPacket(ProxyPacket& packet);
std::pair<s32, Errno> SendTo(u32 flags, const std::vector<u8>& message, std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) override; const SockAddrIn* addr) override;
Errno SetLinger(bool enable, u32 linger) override; Errno SetLinger(bool enable, u32 linger) override;

View file

@ -5,6 +5,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <span>
#include <utility> #include <utility>
#if defined(_WIN32) #if defined(_WIN32)
@ -66,9 +67,9 @@ public:
virtual std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, virtual std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message,
SockAddrIn* addr) = 0; SockAddrIn* addr) = 0;
virtual std::pair<s32, Errno> Send(const std::vector<u8>& message, int flags) = 0; virtual std::pair<s32, Errno> Send(std::span<const u8> message, int flags) = 0;
virtual std::pair<s32, Errno> SendTo(u32 flags, const std::vector<u8>& message, virtual std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) = 0; const SockAddrIn* addr) = 0;
virtual Errno SetLinger(bool enable, u32 linger) = 0; virtual Errno SetLinger(bool enable, u32 linger) = 0;
@ -138,9 +139,9 @@ public:
std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) override; std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) override;
std::pair<s32, Errno> Send(const std::vector<u8>& message, int flags) override; std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
std::pair<s32, Errno> SendTo(u32 flags, const std::vector<u8>& message, std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
const SockAddrIn* addr) override; const SockAddrIn* addr) override;
Errno SetLinger(bool enable, u32 linger) override; Errno SetLinger(bool enable, u32 linger) override;

View file

@ -312,7 +312,7 @@ void Reporter::SaveUnimplementedAppletReport(
} }
void Reporter::SavePlayReport(PlayReportType type, u64 title_id, void Reporter::SavePlayReport(PlayReportType type, u64 title_id,
const std::vector<std::vector<u8>>& data, const std::vector<std::span<const u8>>& data,
std::optional<u64> process_id, std::optional<u128> user_id) const { std::optional<u64> process_id, std::optional<u128> user_id) const {
if (!IsReportingEnabled()) { if (!IsReportingEnabled()) {
return; return;

View file

@ -5,6 +5,7 @@
#include <array> #include <array>
#include <optional> #include <optional>
#include <span>
#include <string> #include <string>
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
@ -56,7 +57,8 @@ public:
System, System,
}; };
void SavePlayReport(PlayReportType type, u64 title_id, const std::vector<std::vector<u8>>& data, void SavePlayReport(PlayReportType type, u64 title_id,
const std::vector<std::span<const u8>>& data,
std::optional<u64> process_id = {}, std::optional<u128> user_id = {}) const; std::optional<u64> process_id = {}, std::optional<u128> user_id = {}) const;
// Used by error applet // Used by error applet

View file

@ -51,8 +51,29 @@ endif()
if (ENABLE_SDL2) if (ENABLE_SDL2)
target_sources(input_common PRIVATE target_sources(input_common PRIVATE
drivers/joycon.cpp
drivers/joycon.h
drivers/sdl_driver.cpp drivers/sdl_driver.cpp
drivers/sdl_driver.h drivers/sdl_driver.h
helpers/joycon_driver.cpp
helpers/joycon_driver.h
helpers/joycon_protocol/calibration.cpp
helpers/joycon_protocol/calibration.h
helpers/joycon_protocol/common_protocol.cpp
helpers/joycon_protocol/common_protocol.h
helpers/joycon_protocol/generic_functions.cpp
helpers/joycon_protocol/generic_functions.h
helpers/joycon_protocol/joycon_types.h
helpers/joycon_protocol/irs.cpp
helpers/joycon_protocol/irs.h
helpers/joycon_protocol/nfc.cpp
helpers/joycon_protocol/nfc.h
helpers/joycon_protocol/poller.cpp
helpers/joycon_protocol/poller.h
helpers/joycon_protocol/ringcon.cpp
helpers/joycon_protocol/ringcon.h
helpers/joycon_protocol/rumble.cpp
helpers/joycon_protocol/rumble.h
) )
target_link_libraries(input_common PRIVATE SDL2::SDL2) target_link_libraries(input_common PRIVATE SDL2::SDL2)
target_compile_definitions(input_common PRIVATE HAVE_SDL2) target_compile_definitions(input_common PRIVATE HAVE_SDL2)

View file

@ -72,11 +72,11 @@ std::size_t Camera::getImageHeight() const {
} }
} }
Common::Input::CameraError Camera::SetCameraFormat( Common::Input::DriverResult Camera::SetCameraFormat(
[[maybe_unused]] const PadIdentifier& identifier_, [[maybe_unused]] const PadIdentifier& identifier_,
const Common::Input::CameraFormat camera_format) { const Common::Input::CameraFormat camera_format) {
status.format = camera_format; status.format = camera_format;
return Common::Input::CameraError::None; return Common::Input::DriverResult::Success;
} }
} // namespace InputCommon } // namespace InputCommon

View file

@ -22,7 +22,7 @@ public:
std::size_t getImageWidth() const; std::size_t getImageWidth() const;
std::size_t getImageHeight() const; std::size_t getImageHeight() const;
Common::Input::CameraError SetCameraFormat(const PadIdentifier& identifier_, Common::Input::DriverResult SetCameraFormat(const PadIdentifier& identifier_,
Common::Input::CameraFormat camera_format) override; Common::Input::CameraFormat camera_format) override;
private: private:

View file

@ -324,7 +324,7 @@ bool GCAdapter::GetGCEndpoint(libusb_device* device) {
return true; return true;
} }
Common::Input::VibrationError GCAdapter::SetVibration( Common::Input::DriverResult GCAdapter::SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f; const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f;
const auto processed_amplitude = const auto processed_amplitude =
@ -333,9 +333,9 @@ Common::Input::VibrationError GCAdapter::SetVibration(
pads[identifier.port].rumble_amplitude = processed_amplitude; pads[identifier.port].rumble_amplitude = processed_amplitude;
if (!rumble_enabled) { if (!rumble_enabled) {
return Common::Input::VibrationError::Disabled; return Common::Input::DriverResult::Disabled;
} }
return Common::Input::VibrationError::None; return Common::Input::DriverResult::Success;
} }
bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) { bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {

View file

@ -25,7 +25,7 @@ public:
explicit GCAdapter(std::string input_engine_); explicit GCAdapter(std::string input_engine_);
~GCAdapter() override; ~GCAdapter() override;
Common::Input::VibrationError SetVibration( Common::Input::DriverResult SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
bool IsVibrationEnabled(const PadIdentifier& identifier) override; bool IsVibrationEnabled(const PadIdentifier& identifier) override;

View file

@ -318,6 +318,15 @@ void SDLDriver::InitJoystick(int joystick_index) {
const auto guid = GetGUID(sdl_joystick); const auto guid = GetGUID(sdl_joystick);
if (Settings::values.enable_joycon_driver) {
if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e &&
(guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) {
LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index);
SDL_JoystickClose(sdl_joystick);
return;
}
}
std::scoped_lock lock{joystick_map_mutex}; std::scoped_lock lock{joystick_map_mutex};
if (joystick_map.find(guid) == joystick_map.end()) { if (joystick_map.find(guid) == joystick_map.end()) {
auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller); auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller);
@ -440,9 +449,13 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
// Use hidapi driver for joycons. This will allow joycons to be detected as a GameController and // Disable hidapi drivers for switch controllers when the custom joycon driver is enabled
// not a generic one if (Settings::values.enable_joycon_driver) {
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "0");
} else {
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1");
}
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1");
// Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native
// driver on Linux. // driver on Linux.
@ -532,7 +545,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const {
return devices; return devices;
} }
Common::Input::VibrationError SDLDriver::SetVibration( Common::Input::DriverResult SDLDriver::SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
const auto joystick = const auto joystick =
GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
@ -566,7 +579,7 @@ Common::Input::VibrationError SDLDriver::SetVibration(
.vibration = new_vibration, .vibration = new_vibration,
}); });
return Common::Input::VibrationError::None; return Common::Input::DriverResult::Success;
} }
bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) { bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) {

View file

@ -63,7 +63,7 @@ public:
bool IsStickInverted(const Common::ParamPackage& params) override; bool IsStickInverted(const Common::ParamPackage& params) override;
Common::Input::VibrationError SetVibration( Common::Input::DriverResult SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
bool IsVibrationEnabled(const PadIdentifier& identifier) override; bool IsVibrationEnabled(const PadIdentifier& identifier) override;

View file

@ -22,22 +22,23 @@ VirtualAmiibo::VirtualAmiibo(std::string input_engine_) : InputEngine(std::move(
VirtualAmiibo::~VirtualAmiibo() = default; VirtualAmiibo::~VirtualAmiibo() = default;
Common::Input::PollingError VirtualAmiibo::SetPollingMode( Common::Input::DriverResult VirtualAmiibo::SetPollingMode(
[[maybe_unused]] const PadIdentifier& identifier_, [[maybe_unused]] const PadIdentifier& identifier_,
const Common::Input::PollingMode polling_mode_) { const Common::Input::PollingMode polling_mode_) {
polling_mode = polling_mode_; polling_mode = polling_mode_;
if (polling_mode == Common::Input::PollingMode::NFC) { switch (polling_mode) {
case Common::Input::PollingMode::NFC:
if (state == State::Initialized) { if (state == State::Initialized) {
state = State::WaitingForAmiibo; state = State::WaitingForAmiibo;
} }
} else { return Common::Input::DriverResult::Success;
default:
if (state == State::AmiiboIsOpen) { if (state == State::AmiiboIsOpen) {
CloseAmiibo(); CloseAmiibo();
} }
return Common::Input::DriverResult::NotSupported;
} }
return Common::Input::PollingError::None;
} }
Common::Input::NfcState VirtualAmiibo::SupportsNfc( Common::Input::NfcState VirtualAmiibo::SupportsNfc(

View file

@ -36,7 +36,7 @@ public:
~VirtualAmiibo() override; ~VirtualAmiibo() override;
// Sets polling mode to a controller // Sets polling mode to a controller
Common::Input::PollingError SetPollingMode( Common::Input::DriverResult SetPollingMode(
const PadIdentifier& identifier_, const Common::Input::PollingMode polling_mode_) override; const PadIdentifier& identifier_, const Common::Input::PollingMode polling_mode_) override;
Common::Input::NfcState SupportsNfc(const PadIdentifier& identifier_) const override; Common::Input::NfcState SupportsNfc(const PadIdentifier& identifier_) const override;

View file

@ -79,6 +79,17 @@ void InputEngine::SetBattery(const PadIdentifier& identifier, Common::Input::Bat
TriggerOnBatteryChange(identifier, value); TriggerOnBatteryChange(identifier, value);
} }
void InputEngine::SetColor(const PadIdentifier& identifier, Common::Input::BodyColorStatus value) {
{
std::scoped_lock lock{mutex};
ControllerData& controller = controller_list.at(identifier);
if (!configuring) {
controller.color = value;
}
}
TriggerOnColorChange(identifier, value);
}
void InputEngine::SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value) { void InputEngine::SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value) {
{ {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
@ -176,6 +187,18 @@ Common::Input::BatteryLevel InputEngine::GetBattery(const PadIdentifier& identif
return controller.battery; return controller.battery;
} }
Common::Input::BodyColorStatus InputEngine::GetColor(const PadIdentifier& identifier) const {
std::scoped_lock lock{mutex};
const auto controller_iter = controller_list.find(identifier);
if (controller_iter == controller_list.cend()) {
LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
identifier.pad, identifier.port);
return {};
}
const ControllerData& controller = controller_iter->second;
return controller.color;
}
BasicMotion InputEngine::GetMotion(const PadIdentifier& identifier, int motion) const { BasicMotion InputEngine::GetMotion(const PadIdentifier& identifier, int motion) const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
const auto controller_iter = controller_list.find(identifier); const auto controller_iter = controller_list.find(identifier);
@ -328,6 +351,20 @@ void InputEngine::TriggerOnBatteryChange(const PadIdentifier& identifier,
} }
} }
void InputEngine::TriggerOnColorChange(const PadIdentifier& identifier,
[[maybe_unused]] Common::Input::BodyColorStatus value) {
std::scoped_lock lock{mutex_callback};
for (const auto& poller_pair : callback_list) {
const InputIdentifier& poller = poller_pair.second;
if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Color, 0)) {
continue;
}
if (poller.callback.on_change) {
poller.callback.on_change();
}
}
}
void InputEngine::TriggerOnMotionChange(const PadIdentifier& identifier, int motion, void InputEngine::TriggerOnMotionChange(const PadIdentifier& identifier, int motion,
const BasicMotion& value) { const BasicMotion& value) {
std::scoped_lock lock{mutex_callback}; std::scoped_lock lock{mutex_callback};

View file

@ -40,6 +40,7 @@ enum class EngineInputType {
Battery, Battery,
Button, Button,
Camera, Camera,
Color,
HatButton, HatButton,
Motion, Motion,
Nfc, Nfc,
@ -104,14 +105,17 @@ public:
void EndConfiguration(); void EndConfiguration();
// Sets a led pattern for a controller // Sets a led pattern for a controller
virtual void SetLeds([[maybe_unused]] const PadIdentifier& identifier, virtual Common::Input::DriverResult SetLeds(
[[maybe_unused]] const Common::Input::LedStatus& led_status) {} [[maybe_unused]] const PadIdentifier& identifier,
[[maybe_unused]] const Common::Input::LedStatus& led_status) {
return Common::Input::DriverResult::NotSupported;
}
// Sets rumble to a controller // Sets rumble to a controller
virtual Common::Input::VibrationError SetVibration( virtual Common::Input::DriverResult SetVibration(
[[maybe_unused]] const PadIdentifier& identifier, [[maybe_unused]] const PadIdentifier& identifier,
[[maybe_unused]] const Common::Input::VibrationStatus& vibration) { [[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
return Common::Input::VibrationError::NotSupported; return Common::Input::DriverResult::NotSupported;
} }
// Returns true if device supports vibrations // Returns true if device supports vibrations
@ -120,17 +124,17 @@ public:
} }
// Sets polling mode to a controller // Sets polling mode to a controller
virtual Common::Input::PollingError SetPollingMode( virtual Common::Input::DriverResult SetPollingMode(
[[maybe_unused]] const PadIdentifier& identifier, [[maybe_unused]] const PadIdentifier& identifier,
[[maybe_unused]] const Common::Input::PollingMode polling_mode) { [[maybe_unused]] const Common::Input::PollingMode polling_mode) {
return Common::Input::PollingError::NotSupported; return Common::Input::DriverResult::NotSupported;
} }
// Sets camera format to a controller // Sets camera format to a controller
virtual Common::Input::CameraError SetCameraFormat( virtual Common::Input::DriverResult SetCameraFormat(
[[maybe_unused]] const PadIdentifier& identifier, [[maybe_unused]] const PadIdentifier& identifier,
[[maybe_unused]] Common::Input::CameraFormat camera_format) { [[maybe_unused]] Common::Input::CameraFormat camera_format) {
return Common::Input::CameraError::NotSupported; return Common::Input::DriverResult::NotSupported;
} }
// Returns success if nfc is supported // Returns success if nfc is supported
@ -199,6 +203,7 @@ public:
bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const; bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const;
f32 GetAxis(const PadIdentifier& identifier, int axis) const; f32 GetAxis(const PadIdentifier& identifier, int axis) const;
Common::Input::BatteryLevel GetBattery(const PadIdentifier& identifier) const; Common::Input::BatteryLevel GetBattery(const PadIdentifier& identifier) const;
Common::Input::BodyColorStatus GetColor(const PadIdentifier& identifier) const;
BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const; BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const;
Common::Input::CameraStatus GetCamera(const PadIdentifier& identifier) const; Common::Input::CameraStatus GetCamera(const PadIdentifier& identifier) const;
Common::Input::NfcStatus GetNfc(const PadIdentifier& identifier) const; Common::Input::NfcStatus GetNfc(const PadIdentifier& identifier) const;
@ -212,6 +217,7 @@ protected:
void SetHatButton(const PadIdentifier& identifier, int button, u8 value); void SetHatButton(const PadIdentifier& identifier, int button, u8 value);
void SetAxis(const PadIdentifier& identifier, int axis, f32 value); void SetAxis(const PadIdentifier& identifier, int axis, f32 value);
void SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value); void SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value);
void SetColor(const PadIdentifier& identifier, Common::Input::BodyColorStatus value);
void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value); void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value);
void SetCamera(const PadIdentifier& identifier, const Common::Input::CameraStatus& value); void SetCamera(const PadIdentifier& identifier, const Common::Input::CameraStatus& value);
void SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value); void SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value);
@ -227,6 +233,7 @@ private:
std::unordered_map<int, float> axes; std::unordered_map<int, float> axes;
std::unordered_map<int, BasicMotion> motions; std::unordered_map<int, BasicMotion> motions;
Common::Input::BatteryLevel battery{}; Common::Input::BatteryLevel battery{};
Common::Input::BodyColorStatus color{};
Common::Input::CameraStatus camera{}; Common::Input::CameraStatus camera{};
Common::Input::NfcStatus nfc{}; Common::Input::NfcStatus nfc{};
}; };
@ -235,6 +242,8 @@ private:
void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value); void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value);
void TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value); void TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value);
void TriggerOnBatteryChange(const PadIdentifier& identifier, Common::Input::BatteryLevel value); void TriggerOnBatteryChange(const PadIdentifier& identifier, Common::Input::BatteryLevel value);
void TriggerOnColorChange(const PadIdentifier& identifier,
Common::Input::BodyColorStatus value);
void TriggerOnMotionChange(const PadIdentifier& identifier, int motion, void TriggerOnMotionChange(const PadIdentifier& identifier, int motion,
const BasicMotion& value); const BasicMotion& value);
void TriggerOnCameraChange(const PadIdentifier& identifier, void TriggerOnCameraChange(const PadIdentifier& identifier,

View file

@ -498,6 +498,58 @@ private:
InputEngine* input_engine; InputEngine* input_engine;
}; };
class InputFromColor final : public Common::Input::InputDevice {
public:
explicit InputFromColor(PadIdentifier identifier_, InputEngine* input_engine_)
: identifier(identifier_), input_engine(input_engine_) {
UpdateCallback engine_callback{[this]() { OnChange(); }};
const InputIdentifier input_identifier{
.identifier = identifier,
.type = EngineInputType::Color,
.index = 0,
.callback = engine_callback,
};
last_color_value = {};
callback_key = input_engine->SetCallback(input_identifier);
}
~InputFromColor() override {
input_engine->DeleteCallback(callback_key);
}
Common::Input::BodyColorStatus GetStatus() const {
return input_engine->GetColor(identifier);
}
void ForceUpdate() override {
const Common::Input::CallbackStatus status{
.type = Common::Input::InputType::Color,
.color_status = GetStatus(),
};
last_color_value = status.color_status;
TriggerOnChange(status);
}
void OnChange() {
const Common::Input::CallbackStatus status{
.type = Common::Input::InputType::Color,
.color_status = GetStatus(),
};
if (status.color_status.body != last_color_value.body) {
last_color_value = status.color_status;
TriggerOnChange(status);
}
}
private:
const PadIdentifier identifier;
int callback_key;
Common::Input::BodyColorStatus last_color_value;
InputEngine* input_engine;
};
class InputFromMotion final : public Common::Input::InputDevice { class InputFromMotion final : public Common::Input::InputDevice {
public: public:
explicit InputFromMotion(PadIdentifier identifier_, int motion_sensor_, float gyro_threshold_, explicit InputFromMotion(PadIdentifier identifier_, int motion_sensor_, float gyro_threshold_,
@ -754,11 +806,11 @@ public:
explicit OutputFromIdentifier(PadIdentifier identifier_, InputEngine* input_engine_) explicit OutputFromIdentifier(PadIdentifier identifier_, InputEngine* input_engine_)
: identifier(identifier_), input_engine(input_engine_) {} : identifier(identifier_), input_engine(input_engine_) {}
void SetLED(const Common::Input::LedStatus& led_status) override { Common::Input::DriverResult SetLED(const Common::Input::LedStatus& led_status) override {
input_engine->SetLeds(identifier, led_status); return input_engine->SetLeds(identifier, led_status);
} }
Common::Input::VibrationError SetVibration( Common::Input::DriverResult SetVibration(
const Common::Input::VibrationStatus& vibration_status) override { const Common::Input::VibrationStatus& vibration_status) override {
return input_engine->SetVibration(identifier, vibration_status); return input_engine->SetVibration(identifier, vibration_status);
} }
@ -767,11 +819,12 @@ public:
return input_engine->IsVibrationEnabled(identifier); return input_engine->IsVibrationEnabled(identifier);
} }
Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override { Common::Input::DriverResult SetPollingMode(Common::Input::PollingMode polling_mode) override {
return input_engine->SetPollingMode(identifier, polling_mode); return input_engine->SetPollingMode(identifier, polling_mode);
} }
Common::Input::CameraError SetCameraFormat(Common::Input::CameraFormat camera_format) override { Common::Input::DriverResult SetCameraFormat(
Common::Input::CameraFormat camera_format) override {
return input_engine->SetCameraFormat(identifier, camera_format); return input_engine->SetCameraFormat(identifier, camera_format);
} }
@ -966,6 +1019,18 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateBatteryDevice(
return std::make_unique<InputFromBattery>(identifier, input_engine.get()); return std::make_unique<InputFromBattery>(identifier, input_engine.get());
} }
std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateColorDevice(
const Common::ParamPackage& params) {
const PadIdentifier identifier = {
.guid = Common::UUID{params.Get("guid", "")},
.port = static_cast<std::size_t>(params.Get("port", 0)),
.pad = static_cast<std::size_t>(params.Get("pad", 0)),
};
input_engine->PreSetController(identifier);
return std::make_unique<InputFromColor>(identifier, input_engine.get());
}
std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateMotionDevice( std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateMotionDevice(
Common::ParamPackage params) { Common::ParamPackage params) {
const PadIdentifier identifier = { const PadIdentifier identifier = {
@ -1053,6 +1118,9 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::Create(
if (params.Has("battery")) { if (params.Has("battery")) {
return CreateBatteryDevice(params); return CreateBatteryDevice(params);
} }
if (params.Has("color")) {
return CreateColorDevice(params);
}
if (params.Has("camera")) { if (params.Has("camera")) {
return CreateCameraDevice(params); return CreateCameraDevice(params);
} }

View file

@ -190,6 +190,17 @@ private:
std::unique_ptr<Common::Input::InputDevice> CreateBatteryDevice( std::unique_ptr<Common::Input::InputDevice> CreateBatteryDevice(
const Common::ParamPackage& params); const Common::ParamPackage& params);
/**
* Creates a color device from the parameters given.
* @param params contains parameters for creating the device:
* - "guid": text string for identifying controllers
* - "port": port of the connected device
* - "pad": slot of the connected controller
* @returns a unique input device with the parameters specified
*/
std::unique_ptr<Common::Input::InputDevice> CreateColorDevice(
const Common::ParamPackage& params);
/** /**
* Creates a motion device from the parameters given. * Creates a motion device from the parameters given.
* @param params contains parameters for creating the device: * @param params contains parameters for creating the device:

View file

@ -23,6 +23,7 @@
#include "input_common/drivers/gc_adapter.h" #include "input_common/drivers/gc_adapter.h"
#endif #endif
#ifdef HAVE_SDL2 #ifdef HAVE_SDL2
#include "input_common/drivers/joycon.h"
#include "input_common/drivers/sdl_driver.h" #include "input_common/drivers/sdl_driver.h"
#endif #endif
@ -81,6 +82,7 @@ struct InputSubsystem::Impl {
RegisterEngine("virtual_gamepad", virtual_gamepad); RegisterEngine("virtual_gamepad", virtual_gamepad);
#ifdef HAVE_SDL2 #ifdef HAVE_SDL2
RegisterEngine("sdl", sdl); RegisterEngine("sdl", sdl);
RegisterEngine("joycon", joycon);
#endif #endif
Common::Input::RegisterInputFactory("touch_from_button", Common::Input::RegisterInputFactory("touch_from_button",
@ -111,6 +113,7 @@ struct InputSubsystem::Impl {
UnregisterEngine(virtual_gamepad); UnregisterEngine(virtual_gamepad);
#ifdef HAVE_SDL2 #ifdef HAVE_SDL2
UnregisterEngine(sdl); UnregisterEngine(sdl);
UnregisterEngine(joycon);
#endif #endif
Common::Input::UnregisterInputFactory("touch_from_button"); Common::Input::UnregisterInputFactory("touch_from_button");
@ -133,6 +136,8 @@ struct InputSubsystem::Impl {
auto udp_devices = udp_client->GetInputDevices(); auto udp_devices = udp_client->GetInputDevices();
devices.insert(devices.end(), udp_devices.begin(), udp_devices.end()); devices.insert(devices.end(), udp_devices.begin(), udp_devices.end());
#ifdef HAVE_SDL2 #ifdef HAVE_SDL2
auto joycon_devices = joycon->GetInputDevices();
devices.insert(devices.end(), joycon_devices.begin(), joycon_devices.end());
auto sdl_devices = sdl->GetInputDevices(); auto sdl_devices = sdl->GetInputDevices();
devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end()); devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end());
#endif #endif
@ -164,6 +169,9 @@ struct InputSubsystem::Impl {
if (engine == sdl->GetEngineName()) { if (engine == sdl->GetEngineName()) {
return sdl; return sdl;
} }
if (engine == joycon->GetEngineName()) {
return joycon;
}
#endif #endif
return nullptr; return nullptr;
} }
@ -247,6 +255,9 @@ struct InputSubsystem::Impl {
if (engine == sdl->GetEngineName()) { if (engine == sdl->GetEngineName()) {
return true; return true;
} }
if (engine == joycon->GetEngineName()) {
return true;
}
#endif #endif
return false; return false;
} }
@ -260,6 +271,7 @@ struct InputSubsystem::Impl {
udp_client->BeginConfiguration(); udp_client->BeginConfiguration();
#ifdef HAVE_SDL2 #ifdef HAVE_SDL2
sdl->BeginConfiguration(); sdl->BeginConfiguration();
joycon->BeginConfiguration();
#endif #endif
} }
@ -272,6 +284,7 @@ struct InputSubsystem::Impl {
udp_client->EndConfiguration(); udp_client->EndConfiguration();
#ifdef HAVE_SDL2 #ifdef HAVE_SDL2
sdl->EndConfiguration(); sdl->EndConfiguration();
joycon->EndConfiguration();
#endif #endif
} }
@ -304,6 +317,7 @@ struct InputSubsystem::Impl {
#ifdef HAVE_SDL2 #ifdef HAVE_SDL2
std::shared_ptr<SDLDriver> sdl; std::shared_ptr<SDLDriver> sdl;
std::shared_ptr<Joycons> joycon;
#endif #endif
}; };

View file

@ -440,6 +440,7 @@ void Config::ReadControlValues() {
ReadBasicSetting(Settings::values.emulate_analog_keyboard); ReadBasicSetting(Settings::values.emulate_analog_keyboard);
Settings::values.mouse_panning = false; Settings::values.mouse_panning = false;
ReadBasicSetting(Settings::values.mouse_panning_sensitivity); ReadBasicSetting(Settings::values.mouse_panning_sensitivity);
ReadBasicSetting(Settings::values.enable_joycon_driver);
ReadBasicSetting(Settings::values.tas_enable); ReadBasicSetting(Settings::values.tas_enable);
ReadBasicSetting(Settings::values.tas_loop); ReadBasicSetting(Settings::values.tas_loop);
@ -1139,6 +1140,7 @@ void Config::SaveControlValues() {
WriteGlobalSetting(Settings::values.enable_accurate_vibrations); WriteGlobalSetting(Settings::values.enable_accurate_vibrations);
WriteGlobalSetting(Settings::values.motion_enabled); WriteGlobalSetting(Settings::values.motion_enabled);
WriteBasicSetting(Settings::values.enable_raw_input); WriteBasicSetting(Settings::values.enable_raw_input);
WriteBasicSetting(Settings::values.enable_joycon_driver);
WriteBasicSetting(Settings::values.keyboard_enabled); WriteBasicSetting(Settings::values.keyboard_enabled);
WriteBasicSetting(Settings::values.emulate_analog_keyboard); WriteBasicSetting(Settings::values.emulate_analog_keyboard);
WriteBasicSetting(Settings::values.mouse_panning_sensitivity); WriteBasicSetting(Settings::values.mouse_panning_sensitivity);

View file

@ -138,6 +138,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() {
Settings::values.controller_navigation = ui->controller_navigation->isChecked(); Settings::values.controller_navigation = ui->controller_navigation->isChecked();
Settings::values.enable_ring_controller = ui->enable_ring_controller->isChecked(); Settings::values.enable_ring_controller = ui->enable_ring_controller->isChecked();
Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked(); Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked();
Settings::values.enable_joycon_driver = ui->enable_joycon_driver->isChecked();
} }
void ConfigureInputAdvanced::LoadConfiguration() { void ConfigureInputAdvanced::LoadConfiguration() {
@ -172,6 +173,7 @@ void ConfigureInputAdvanced::LoadConfiguration() {
ui->controller_navigation->setChecked(Settings::values.controller_navigation.GetValue()); ui->controller_navigation->setChecked(Settings::values.controller_navigation.GetValue());
ui->enable_ring_controller->setChecked(Settings::values.enable_ring_controller.GetValue()); ui->enable_ring_controller->setChecked(Settings::values.enable_ring_controller.GetValue());
ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue()); ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue());
ui->enable_joycon_driver->setChecked(Settings::values.enable_joycon_driver.GetValue());
UpdateUIEnabled(); UpdateUIEnabled();
} }

View file

@ -2696,6 +2696,22 @@
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="5" column="0">
<widget class="QCheckBox" name="enable_joycon_driver">
<property name="toolTip">
<string>Requires restarting yuzu</string>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Enable direct JoyCon driver</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="mouse_panning"> <widget class="QCheckBox" name="mouse_panning">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@ -2708,7 +2724,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="2"> <item row="6" column="2">
<widget class="QSpinBox" name="mouse_panning_sensitivity"> <widget class="QSpinBox" name="mouse_panning_sensitivity">
<property name="toolTip"> <property name="toolTip">
<string>Mouse sensitivity</string> <string>Mouse sensitivity</string>
@ -2730,14 +2746,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="7" column="0">
<widget class="QLabel" name="motion_touch"> <widget class="QLabel" name="motion_touch">
<property name="text"> <property name="text">
<string>Motion / Touch</string> <string>Motion / Touch</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="2"> <item row="7" column="2">
<widget class="QPushButton" name="buttonMotionTouch"> <widget class="QPushButton" name="buttonMotionTouch">
<property name="text"> <property name="text">
<string>Configure</string> <string>Configure</string>

View file

@ -66,6 +66,18 @@ QString GetButtonName(Common::Input::ButtonNames button_name) {
return QObject::tr("R"); return QObject::tr("R");
case Common::Input::ButtonNames::TriggerL: case Common::Input::ButtonNames::TriggerL:
return QObject::tr("L"); return QObject::tr("L");
case Common::Input::ButtonNames::TriggerZR:
return QObject::tr("ZR");
case Common::Input::ButtonNames::TriggerZL:
return QObject::tr("ZL");
case Common::Input::ButtonNames::TriggerSR:
return QObject::tr("SR");
case Common::Input::ButtonNames::TriggerSL:
return QObject::tr("SL");
case Common::Input::ButtonNames::ButtonStickL:
return QObject::tr("Stick L");
case Common::Input::ButtonNames::ButtonStickR:
return QObject::tr("Stick R");
case Common::Input::ButtonNames::ButtonA: case Common::Input::ButtonNames::ButtonA:
return QObject::tr("A"); return QObject::tr("A");
case Common::Input::ButtonNames::ButtonB: case Common::Input::ButtonNames::ButtonB:
@ -76,6 +88,14 @@ QString GetButtonName(Common::Input::ButtonNames button_name) {
return QObject::tr("Y"); return QObject::tr("Y");
case Common::Input::ButtonNames::ButtonStart: case Common::Input::ButtonNames::ButtonStart:
return QObject::tr("Start"); return QObject::tr("Start");
case Common::Input::ButtonNames::ButtonPlus:
return QObject::tr("Plus");
case Common::Input::ButtonNames::ButtonMinus:
return QObject::tr("Minus");
case Common::Input::ButtonNames::ButtonHome:
return QObject::tr("Home");
case Common::Input::ButtonNames::ButtonCapture:
return QObject::tr("Capture");
case Common::Input::ButtonNames::L1: case Common::Input::ButtonNames::L1:
return QObject::tr("L1"); return QObject::tr("L1");
case Common::Input::ButtonNames::L2: case Common::Input::ButtonNames::L2:

View file

@ -103,9 +103,13 @@ void PlayerControlPreview::UpdateColors() {
colors.left = colors.primary; colors.left = colors.primary;
colors.right = colors.primary; colors.right = colors.primary;
// Possible alternative to set colors from settings
// colors.left = QColor(controller->GetColors().left.body); const auto color_left = controller->GetColorsValues()[0].body;
// colors.right = QColor(controller->GetColors().right.body); const auto color_right = controller->GetColorsValues()[1].body;
if (color_left != 0 && color_right != 0) {
colors.left = QColor(color_left);
colors.right = QColor(color_right);
}
} }
void PlayerControlPreview::ResetInputs() { void PlayerControlPreview::ResetInputs() {

Some files were not shown because too many files have changed in this diff Show more