Merge remote-tracking branch 'sunshine/master'
This commit is contained in:
@@ -665,9 +665,13 @@ namespace config {
|
||||
// Lists might contain newlines
|
||||
if (*begin_val == '[') {
|
||||
endl = skip_list(begin_val + 1, end);
|
||||
if (endl == end) {
|
||||
std::cout << "Warning: Config option ["sv << to_string(begin, end_name) << "] Missing ']'"sv;
|
||||
|
||||
// Check if we reached the end of the file without finding a closing bracket
|
||||
// We know we have a valid closing bracket if:
|
||||
// 1. We didn't reach the end, or
|
||||
// 2. We reached the end but the last character was the matching closing bracket
|
||||
if (endl == end && end == begin_val + 1) {
|
||||
BOOST_LOG(warning) << "config: Missing ']' in config option: " << to_string(begin, end_name);
|
||||
return std::make_pair(endl, std::nullopt);
|
||||
}
|
||||
}
|
||||
@@ -1027,7 +1031,7 @@ namespace config {
|
||||
|
||||
// The list needs to be a multiple of 2
|
||||
if (list.size() % 2) {
|
||||
std::cout << "Warning: expected "sv << name << " to have a multiple of two elements --> not "sv << list.size() << std::endl;
|
||||
BOOST_LOG(warning) << "config: expected "sv << name << " to have a multiple of two elements --> not "sv << list.size();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1057,7 +1061,7 @@ namespace config {
|
||||
config::sunshine.flags[config::flag::UPNP].flip();
|
||||
break;
|
||||
default:
|
||||
std::cout << "Warning: Unrecognized flag: ["sv << *line << ']' << std::endl;
|
||||
BOOST_LOG(warning) << "config: Unrecognized flag: ["sv << *line << ']' << std::endl;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
@@ -1083,11 +1087,7 @@ namespace config {
|
||||
}
|
||||
|
||||
for (auto &[name, val] : vars) {
|
||||
#ifdef _WIN32
|
||||
std::cout << "["sv << name << "] -- ["sv << utf8ToAcp(val) << ']' << std::endl;
|
||||
#else
|
||||
std::cout << "["sv << name << "] -- ["sv << val << ']' << std::endl;
|
||||
#endif
|
||||
BOOST_LOG(info) << "config: '"sv << name << "' = "sv << val;
|
||||
}
|
||||
|
||||
bool_f(vars, "headless_mode", video.headless_mode);
|
||||
@@ -1485,7 +1485,7 @@ namespace config {
|
||||
shell_exec_info.nShow = SW_NORMAL;
|
||||
if (!ShellExecuteExW(&shell_exec_info)) {
|
||||
auto winerr = GetLastError();
|
||||
std::cout << "Error: ShellExecuteEx() failed:"sv << winerr << std::endl;
|
||||
BOOST_LOG(error) << "Failed executing shell command: " << winerr << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,10 +108,6 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
mail::man = std::make_shared<safe::mail_raw_t>();
|
||||
|
||||
if (config::parse(argc, argv)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto log_deinit_guard = logging::init(config::sunshine.min_log_level, config::sunshine.log_file);
|
||||
if (!log_deinit_guard) {
|
||||
BOOST_LOG(error) << "Logging failed to initialize"sv;
|
||||
@@ -125,6 +121,11 @@ int main(int argc, char *argv[]) {
|
||||
// Log publisher metadata
|
||||
log_publisher_data();
|
||||
|
||||
// parse config file
|
||||
if (config::parse(argc, argv)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!config::sunshine.cmd.name.empty()) {
|
||||
auto fn = cmd_to_func.find(config::sunshine.cmd.name);
|
||||
if (fn == std::end(cmd_to_func)) {
|
||||
|
||||
@@ -106,6 +106,7 @@ namespace platf {
|
||||
rumble_triggers, ///< Rumble triggers
|
||||
set_motion_event_state, ///< Set motion event state
|
||||
set_rgb_led, ///< Set RGB LED
|
||||
set_adaptive_triggers, ///< Set adaptive triggers
|
||||
};
|
||||
|
||||
struct gamepad_feedback_msg_t {
|
||||
@@ -142,6 +143,14 @@ namespace platf {
|
||||
return msg;
|
||||
}
|
||||
|
||||
static gamepad_feedback_msg_t make_adaptive_triggers(std::uint16_t id, uint8_t event_flags, uint8_t type_left, uint8_t type_right, const std::array<uint8_t, 10> &left, const std::array<uint8_t, 10> &right) {
|
||||
gamepad_feedback_msg_t msg;
|
||||
msg.type = gamepad_feedback_e::set_adaptive_triggers;
|
||||
msg.id = id;
|
||||
msg.data.adaptive_triggers = {.event_flags = event_flags, .type_left = type_left, .type_right = type_right, .left = left, .right = right};
|
||||
return msg;
|
||||
}
|
||||
|
||||
gamepad_feedback_e type;
|
||||
std::uint16_t id;
|
||||
|
||||
@@ -166,6 +175,15 @@ namespace platf {
|
||||
std::uint8_t g;
|
||||
std::uint8_t b;
|
||||
} rgb_led;
|
||||
|
||||
struct {
|
||||
uint16_t controllerNumber;
|
||||
uint8_t event_flags;
|
||||
uint8_t type_left;
|
||||
uint8_t type_right;
|
||||
std::array<uint8_t, 10> left;
|
||||
std::array<uint8_t, 10> right;
|
||||
} adaptive_triggers;
|
||||
} data;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace platf::gamepad {
|
||||
}
|
||||
|
||||
auto create_ds5() {
|
||||
return inputtino::PS5Joypad::create({.name = "Sunshine DualSense (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111});
|
||||
return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111});
|
||||
}
|
||||
|
||||
int alloc(input_raw_t *raw, const gamepad_id_t &id, const gamepad_arrival_t &metadata, feedback_queue_t feedback_queue) {
|
||||
@@ -152,6 +152,10 @@ namespace platf::gamepad {
|
||||
gamepad->last_rgb_led = msg;
|
||||
});
|
||||
|
||||
(*ds5).set_on_trigger_effect([feedback_queue, idx = id.clientRelativeIndex](const inputtino::PS5Joypad::TriggerEffect &trigger_effect) {
|
||||
feedback_queue->raise(gamepad_feedback_msg_t::make_adaptive_triggers(idx, trigger_effect.event_flags, trigger_effect.type_left, trigger_effect.type_right, trigger_effect.left, trigger_effect.right));
|
||||
});
|
||||
|
||||
// Activate the motion sensors
|
||||
feedback_queue->raise(gamepad_feedback_msg_t::make_motion_event_state(id.clientRelativeIndex, LI_MOTION_TYPE_ACCEL, 100));
|
||||
feedback_queue->raise(gamepad_feedback_msg_t::make_motion_event_state(id.clientRelativeIndex, LI_MOTION_TYPE_GYRO, 100));
|
||||
|
||||
@@ -52,6 +52,7 @@ extern "C" {
|
||||
#define IDX_EXEC_SERVER_CMD 15
|
||||
#define IDX_SET_CLIPBOARD 16
|
||||
#define IDX_FILE_TRANSFER_NONCE_REQUEST 17
|
||||
#define IDX_SET_ADAPTIVE_TRIGGERS 18
|
||||
|
||||
static const short packetTypes[] = {
|
||||
0x0305, // Start A
|
||||
@@ -72,6 +73,7 @@ static const short packetTypes[] = {
|
||||
0x3000, // Execute Server Command (Apollo protocol extension)
|
||||
0x3001, // Set Clipboard (Apollo protocol extension)
|
||||
0x3002, // File transfer nonce request (Apollo protocol extension)
|
||||
0x5503, // Set Adaptive triggers (Sunshine protocol extension)
|
||||
};
|
||||
|
||||
namespace asio = boost::asio;
|
||||
@@ -193,6 +195,21 @@ namespace stream {
|
||||
std::uint8_t b;
|
||||
};
|
||||
|
||||
struct control_adaptive_triggers_t {
|
||||
control_header_v2 header;
|
||||
|
||||
std::uint16_t id;
|
||||
/**
|
||||
* 0x04 - Right trigger
|
||||
* 0x08 - Left trigger
|
||||
*/
|
||||
std::uint8_t event_flags;
|
||||
std::uint8_t type_left;
|
||||
std::uint8_t type_right;
|
||||
std::uint8_t left[DS_EFFECT_PAYLOAD_SIZE];
|
||||
std::uint8_t right[DS_EFFECT_PAYLOAD_SIZE];
|
||||
};
|
||||
|
||||
struct control_hdr_mode_t {
|
||||
control_header_v2 header;
|
||||
|
||||
@@ -846,6 +863,22 @@ namespace stream {
|
||||
plaintext.b = data.b;
|
||||
|
||||
BOOST_LOG(verbose) << "RGB: "sv << msg.id << " :: "sv << util::hex(data.r).to_string_view() << util::hex(data.g).to_string_view() << util::hex(data.b).to_string_view();
|
||||
std::array<std::uint8_t, sizeof(control_encrypted_t) + crypto::cipher::round_to_pkcs7_padded(sizeof(plaintext)) + crypto::cipher::tag_size>
|
||||
encrypted_payload;
|
||||
|
||||
payload = encode_control(session, util::view(plaintext), encrypted_payload);
|
||||
} else if (msg.type == platf::gamepad_feedback_e::set_adaptive_triggers) {
|
||||
control_adaptive_triggers_t plaintext;
|
||||
plaintext.header.type = packetTypes[IDX_SET_ADAPTIVE_TRIGGERS];
|
||||
plaintext.header.payloadLength = sizeof(plaintext) - sizeof(control_header_v2);
|
||||
|
||||
plaintext.id = util::endian::little(msg.id);
|
||||
plaintext.event_flags = msg.data.adaptive_triggers.event_flags;
|
||||
plaintext.type_left = msg.data.adaptive_triggers.type_left;
|
||||
std::ranges::copy(msg.data.adaptive_triggers.left, plaintext.left);
|
||||
plaintext.type_right = msg.data.adaptive_triggers.type_right;
|
||||
std::ranges::copy(msg.data.adaptive_triggers.right, plaintext.right);
|
||||
|
||||
std::array<std::uint8_t, sizeof(control_encrypted_t) + crypto::cipher::round_to_pkcs7_padded(sizeof(plaintext)) + crypto::cipher::tag_size>
|
||||
encrypted_payload;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user