mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-07-06 04:52:09 -07:00
lib: Add support for trigger effects and controller haptics
By default, no trigger effects and haptics are requested from the console, lib users have to explicitly enable them for a session by setting the new `enable_dualsense` flag on the session's `ChiakiConnectInfo` struct. Trigger Effects are simply a new Takion message type `11` and include the type of each effect and the effect data (10 bytes) for each of the triggers. They are exposed as a new Chiaki event type `CHIAKI_EVENT_TRIGGER_EFFECTS`. Haptic effects are implemented in the protocol as a separate audio stream, for which packets are only sent when there are actually effects being played, i.e. silence is not explicitly encoded. Audio data is 3kHz little endian 16 bit stereo sent in frames of 10 samples every 100ms. Note that the Takion AV header has the codec field set to Opus, however this is not true. Users can provide a new `ChiakiAudioSink` dedicated to haptics via the new `chiaki_session_set_haptics_sink` API, which behaves identical to the regular audio sink, except that it has a lower frequency.
This commit is contained in:
parent
40a9dee4ed
commit
74d39e6314
11 changed files with 145 additions and 28 deletions
|
@ -38,7 +38,7 @@ CHIAKI_EXPORT void chiaki_feedback_state_format_v9(uint8_t *buf, ChiakiFeedbackS
|
|||
/**
|
||||
* @param buf buffer of at least CHIAKI_FEEDBACK_STATE_BUF_SIZE_V12
|
||||
*/
|
||||
CHIAKI_EXPORT void chiaki_feedback_state_format_v12(uint8_t *buf, ChiakiFeedbackState *state);
|
||||
CHIAKI_EXPORT void chiaki_feedback_state_format_v12(uint8_t *buf, ChiakiFeedbackState *state, bool enable_dualsense);
|
||||
|
||||
#define CHIAKI_HISTORY_EVENT_SIZE_MAX 0x5
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ typedef struct chiaki_connect_info_t
|
|||
ChiakiConnectVideoProfile video_profile;
|
||||
bool video_profile_auto_downgrade; // Downgrade video_profile if server does not seem to support it.
|
||||
bool enable_keyboard;
|
||||
bool enable_dualsense;
|
||||
} ChiakiConnectInfo;
|
||||
|
||||
|
||||
|
@ -121,6 +122,14 @@ typedef struct chiaki_rumble_event_t
|
|||
uint8_t right; // high-frequency
|
||||
} ChiakiRumbleEvent;
|
||||
|
||||
typedef struct chiaki_trigger_effects_event_t
|
||||
{
|
||||
uint8_t type_left;
|
||||
uint8_t type_right;
|
||||
uint8_t left[10];
|
||||
uint8_t right[10];
|
||||
} ChiakiTriggerEffectsEvent;
|
||||
|
||||
typedef enum {
|
||||
CHIAKI_EVENT_CONNECTED,
|
||||
CHIAKI_EVENT_LOGIN_PIN_REQUEST,
|
||||
|
@ -129,6 +138,7 @@ typedef enum {
|
|||
CHIAKI_EVENT_KEYBOARD_REMOTE_CLOSE,
|
||||
CHIAKI_EVENT_RUMBLE,
|
||||
CHIAKI_EVENT_QUIT,
|
||||
CHIAKI_EVENT_TRIGGER_EFFECTS,
|
||||
} ChiakiEventType;
|
||||
|
||||
typedef struct chiaki_event_t
|
||||
|
@ -139,6 +149,7 @@ typedef struct chiaki_event_t
|
|||
ChiakiQuitEvent quit;
|
||||
ChiakiKeyboardEvent keyboard;
|
||||
ChiakiRumbleEvent rumble;
|
||||
ChiakiTriggerEffectsEvent trigger_effects;
|
||||
struct
|
||||
{
|
||||
bool pin_incorrect; // false on first request, true if the pin entered before was incorrect
|
||||
|
@ -170,6 +181,7 @@ typedef struct chiaki_session_t
|
|||
ChiakiConnectVideoProfile video_profile;
|
||||
bool video_profile_auto_downgrade;
|
||||
bool enable_keyboard;
|
||||
bool enable_dualsense;
|
||||
} connect_info;
|
||||
|
||||
ChiakiTarget target;
|
||||
|
@ -191,6 +203,7 @@ typedef struct chiaki_session_t
|
|||
ChiakiVideoSampleCallback video_sample_cb;
|
||||
void *video_sample_cb_user;
|
||||
ChiakiAudioSink audio_sink;
|
||||
ChiakiAudioSink haptics_sink;
|
||||
|
||||
ChiakiThread session_thread;
|
||||
|
||||
|
@ -246,6 +259,14 @@ static inline void chiaki_session_set_audio_sink(ChiakiSession *session, ChiakiA
|
|||
session->audio_sink = *sink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sink contents are copied
|
||||
*/
|
||||
static inline void chiaki_session_set_haptics_sink(ChiakiSession *session, ChiakiAudioSink *sink)
|
||||
{
|
||||
session->haptics_sink = *sink;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef struct chiaki_stream_connection_t
|
|||
ChiakiPacketStats packet_stats;
|
||||
ChiakiAudioReceiver *audio_receiver;
|
||||
ChiakiVideoReceiver *video_receiver;
|
||||
ChiakiAudioReceiver *haptics_receiver;
|
||||
|
||||
ChiakiFeedbackSender feedback_sender;
|
||||
/**
|
||||
|
|
|
@ -27,7 +27,8 @@ extern "C" {
|
|||
typedef enum chiaki_takion_message_data_type_t {
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_PROTOBUF = 0,
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_RUMBLE = 7,
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_9 = 9
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_9 = 9,
|
||||
CHIAKI_TAKION_MESSAGE_DATA_TYPE_TRIGGER_EFFECTS = 11,
|
||||
} ChiakiTakionMessageDataType;
|
||||
|
||||
typedef struct chiaki_takion_av_packet_t
|
||||
|
@ -36,6 +37,7 @@ typedef struct chiaki_takion_av_packet_t
|
|||
ChiakiSeqNum16 frame_index;
|
||||
bool uses_nalu_info_structs;
|
||||
bool is_video;
|
||||
bool is_haptics;
|
||||
ChiakiSeqNum16 unit_index;
|
||||
uint16_t units_in_frame_total; // source + units_in_frame_fec
|
||||
uint16_t units_in_frame_fec;
|
||||
|
@ -46,8 +48,6 @@ typedef struct chiaki_takion_av_packet_t
|
|||
|
||||
uint64_t key_pos;
|
||||
|
||||
uint8_t byte_before_audio_data;
|
||||
|
||||
uint8_t *data; // not owned
|
||||
size_t data_size;
|
||||
} ChiakiTakionAVPacket;
|
||||
|
@ -106,6 +106,7 @@ typedef struct chiaki_takion_connect_info_t
|
|||
ChiakiTakionCallback cb;
|
||||
void *cb_user;
|
||||
bool enable_crypt;
|
||||
bool enable_dualsense;
|
||||
uint8_t protocol_version;
|
||||
} ChiakiTakionConnectInfo;
|
||||
|
||||
|
@ -162,6 +163,8 @@ typedef struct chiaki_takion_t
|
|||
ChiakiTakionAVPacketParse av_packet_parse;
|
||||
|
||||
ChiakiKeyState key_state;
|
||||
|
||||
bool enable_dualsense;
|
||||
} ChiakiTakion;
|
||||
|
||||
|
||||
|
|
|
@ -312,7 +312,8 @@ message ControllerConnectionPayload {
|
|||
VITA = 3;
|
||||
XINPUT = 4;
|
||||
MOBILE = 5;
|
||||
BOND = 6;
|
||||
DUALSENSE = 6;
|
||||
VR2SENSE = 7;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, ChiakiSeqNum16 frame_index, uint8_t *buf, size_t buf_size);
|
||||
static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, ChiakiSeqNum16 frame_index, bool is_haptics, uint8_t *buf, size_t buf_size);
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_audio_receiver_init(ChiakiAudioReceiver *audio_receiver, ChiakiSession *session, ChiakiPacketStats *packet_stats)
|
||||
{
|
||||
|
@ -102,14 +102,14 @@ CHIAKI_EXPORT void chiaki_audio_receiver_av_packet(ChiakiAudioReceiver *audio_re
|
|||
frame_index = packet->frame_index - fec_units_count + fec_index;
|
||||
}
|
||||
|
||||
chiaki_audio_receiver_frame(audio_receiver, frame_index, packet->data + unit_size * i, unit_size);
|
||||
chiaki_audio_receiver_frame(audio_receiver, frame_index, packet->is_haptics, packet->data + unit_size * i, unit_size);
|
||||
}
|
||||
|
||||
if(audio_receiver->packet_stats)
|
||||
chiaki_packet_stats_push_seq(audio_receiver->packet_stats, packet->frame_index);
|
||||
}
|
||||
|
||||
static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, ChiakiSeqNum16 frame_index, uint8_t *buf, size_t buf_size)
|
||||
static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, ChiakiSeqNum16 frame_index, bool is_haptics, uint8_t *buf, size_t buf_size)
|
||||
{
|
||||
chiaki_mutex_lock(&audio_receiver->mutex);
|
||||
|
||||
|
@ -117,7 +117,9 @@ static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, Chi
|
|||
goto beach;
|
||||
audio_receiver->frame_index_prev = frame_index;
|
||||
|
||||
if(audio_receiver->session->audio_sink.frame_cb)
|
||||
if(is_haptics && audio_receiver->session->haptics_sink.frame_cb)
|
||||
audio_receiver->session->haptics_sink.frame_cb(buf, buf_size, audio_receiver->session->haptics_sink.user);
|
||||
else if(!is_haptics && audio_receiver->session->audio_sink.frame_cb)
|
||||
audio_receiver->session->audio_sink.frame_cb(buf, buf_size, audio_receiver->session->audio_sink.user);
|
||||
|
||||
beach:
|
||||
|
|
|
@ -488,17 +488,25 @@ static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *
|
|||
|
||||
static void ctrl_enable_optional_features(ChiakiCtrl *ctrl)
|
||||
{
|
||||
if(!ctrl->session->connect_info.enable_keyboard)
|
||||
return;
|
||||
// TODO: Last byte of pre_enable request is random (?)
|
||||
// TODO: Signature ?!
|
||||
uint8_t enable = 1;
|
||||
uint8_t pre_enable[4] = { 0x00, 0x01, 0x01, 0x80 };
|
||||
uint8_t signature[0x10] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
ctrl_message_send(ctrl, 0xD, signature, 0x10);
|
||||
ctrl_message_send(ctrl, 0x36, pre_enable, 4);
|
||||
ctrl_message_send(ctrl, CTRL_MESSAGE_TYPE_KEYBOARD_ENABLE_TOGGLE, &enable, 1);
|
||||
ctrl_message_send(ctrl, 0x36, pre_enable, 4);
|
||||
if(ctrl->session->connect_info.enable_dualsense)
|
||||
{
|
||||
CHIAKI_LOGI(ctrl->session->log, "Enabling DualSense features");
|
||||
const uint8_t enable[3] = { 0x00, 0x40, 0x00 };
|
||||
ctrl_message_send(ctrl, 0x13, enable, 3);
|
||||
}
|
||||
if(ctrl->session->connect_info.enable_keyboard)
|
||||
{
|
||||
CHIAKI_LOGI(ctrl->session->log, "Enabling Keyboard");
|
||||
// TODO: Last byte of pre_enable request is random (?)
|
||||
// TODO: Signature ?!
|
||||
uint8_t enable = 1;
|
||||
uint8_t pre_enable[4] = { 0x00, 0x01, 0x01, 0x80 };
|
||||
uint8_t signature[0x10] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
ctrl_message_send(ctrl, 0xD, signature, 0x10);
|
||||
ctrl_message_send(ctrl, 0x36, pre_enable, 4);
|
||||
ctrl_message_send(ctrl, CTRL_MESSAGE_TYPE_KEYBOARD_ENABLE_TOGGLE, &enable, 1);
|
||||
ctrl_message_send(ctrl, 0x36, pre_enable, 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void ctrl_message_received_session_id(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size)
|
||||
|
|
|
@ -76,12 +76,12 @@ CHIAKI_EXPORT void chiaki_feedback_state_format_v9(uint8_t *buf, ChiakiFeedbackS
|
|||
*((chiaki_unaligned_uint16_t *)(buf + 0x17)) = htons((uint16_t)state->right_y);
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT void chiaki_feedback_state_format_v12(uint8_t *buf, ChiakiFeedbackState *state)
|
||||
CHIAKI_EXPORT void chiaki_feedback_state_format_v12(uint8_t *buf, ChiakiFeedbackState *state, bool enable_dualsense)
|
||||
{
|
||||
chiaki_feedback_state_format_v9(buf, state);
|
||||
buf[0x19] = 0x0;
|
||||
buf[0x1a] = 0x0;
|
||||
buf[0x1b] = 0x1; // 1 for Shock, 0 for Sense
|
||||
buf[0x1b] = enable_dualsense ? 0x0 : 0x1;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFeedbackHistoryEvent *event, uint64_t button, uint8_t state)
|
||||
|
|
|
@ -227,6 +227,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_session_init(ChiakiSession *session, Chiaki
|
|||
session->connect_info.video_profile = connect_info->video_profile;
|
||||
session->connect_info.video_profile_auto_downgrade = connect_info->video_profile_auto_downgrade;
|
||||
session->connect_info.enable_keyboard = connect_info->enable_keyboard;
|
||||
session->connect_info.enable_dualsense = connect_info->enable_dualsense;
|
||||
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
error_stop_pipe:
|
||||
|
|
|
@ -47,7 +47,9 @@ static void stream_connection_takion_cb(ChiakiTakionEvent *event, void *user);
|
|||
static void stream_connection_takion_data(ChiakiStreamConnection *stream_connection, ChiakiTakionMessageDataType data_type, uint8_t *buf, size_t buf_size);
|
||||
static void stream_connection_takion_data_protobuf(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
static void stream_connection_takion_data_rumble(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
static void stream_connection_takion_data_trigger_effects(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream_connection);
|
||||
static ChiakiErrorCode stream_connection_send_controller_connection(ChiakiStreamConnection *stream_connection);
|
||||
static ChiakiErrorCode stream_connection_send_disconnect(ChiakiStreamConnection *stream_connection);
|
||||
static void stream_connection_takion_data_idle(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size);
|
||||
|
@ -79,6 +81,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_init(ChiakiStreamConnecti
|
|||
|
||||
stream_connection->video_receiver = NULL;
|
||||
stream_connection->audio_receiver = NULL;
|
||||
stream_connection->haptics_receiver = NULL;
|
||||
|
||||
err = chiaki_mutex_init(&stream_connection->feedback_sender_mutex, false);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
|
@ -143,6 +146,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_run(ChiakiStreamConnectio
|
|||
takion_info.ip_dontfrag = false;
|
||||
|
||||
takion_info.enable_crypt = true;
|
||||
takion_info.enable_dualsense = session->connect_info.enable_dualsense;
|
||||
takion_info.protocol_version = chiaki_target_is_ps5(session->target) ? 12 : 9;
|
||||
|
||||
takion_info.cb = stream_connection_takion_cb;
|
||||
|
@ -164,12 +168,20 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_run(ChiakiStreamConnectio
|
|||
return CHIAKI_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
stream_connection->haptics_receiver = chiaki_audio_receiver_new(session, NULL);
|
||||
if(!stream_connection->haptics_receiver)
|
||||
{
|
||||
CHIAKI_LOGE(session->log, "StreamConnection failed to initialize Haptics Receiver");
|
||||
err = CHIAKI_ERR_UNKNOWN;
|
||||
goto err_audio_receiver;
|
||||
}
|
||||
|
||||
stream_connection->video_receiver = chiaki_video_receiver_new(session, &stream_connection->packet_stats);
|
||||
if(!stream_connection->video_receiver)
|
||||
{
|
||||
CHIAKI_LOGE(session->log, "StreamConnection failed to initialize Video Receiver");
|
||||
err = CHIAKI_ERR_UNKNOWN;
|
||||
goto err_audio_receiver;
|
||||
goto err_haptics_receiver;
|
||||
}
|
||||
|
||||
stream_connection->state = STATE_TAKION_CONNECT;
|
||||
|
@ -321,6 +333,10 @@ err_video_receiver:
|
|||
chiaki_video_receiver_free(stream_connection->video_receiver);
|
||||
stream_connection->video_receiver = NULL;
|
||||
|
||||
err_haptics_receiver:
|
||||
chiaki_audio_receiver_free(stream_connection->haptics_receiver);
|
||||
stream_connection->haptics_receiver = NULL;
|
||||
|
||||
err_audio_receiver:
|
||||
chiaki_audio_receiver_free(stream_connection->audio_receiver);
|
||||
stream_connection->audio_receiver = NULL;
|
||||
|
@ -376,6 +392,9 @@ static void stream_connection_takion_data(ChiakiStreamConnection *stream_connect
|
|||
case CHIAKI_TAKION_MESSAGE_DATA_TYPE_RUMBLE:
|
||||
stream_connection_takion_data_rumble(stream_connection, buf, buf_size);
|
||||
break;
|
||||
case CHIAKI_TAKION_MESSAGE_DATA_TYPE_TRIGGER_EFFECTS:
|
||||
stream_connection_takion_data_trigger_effects(stream_connection, buf, buf_size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -415,6 +434,24 @@ static void stream_connection_takion_data_rumble(ChiakiStreamConnection *stream_
|
|||
chiaki_session_send_event(stream_connection->session, &event);
|
||||
}
|
||||
|
||||
|
||||
static void stream_connection_takion_data_trigger_effects(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size)
|
||||
{
|
||||
if(buf_size < 25)
|
||||
{
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection got trigger effects packet with size %#llx < 25",
|
||||
(unsigned long long)buf_size);
|
||||
return;
|
||||
}
|
||||
ChiakiEvent event = { 0 };
|
||||
event.type = CHIAKI_EVENT_TRIGGER_EFFECTS;
|
||||
event.trigger_effects.type_left = buf[1];
|
||||
event.trigger_effects.type_right = buf[2];
|
||||
memcpy(&event.trigger_effects.left, buf + 5, 10);
|
||||
memcpy(&event.trigger_effects.right, buf + 15, 10);
|
||||
chiaki_session_send_event(stream_connection->session, &event);
|
||||
}
|
||||
|
||||
static void stream_connection_takion_data_handle_disconnect(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size)
|
||||
{
|
||||
tkproto_TakionMessage msg;
|
||||
|
@ -460,7 +497,7 @@ static void stream_connection_takion_data_idle(ChiakiStreamConnection *stream_co
|
|||
return;
|
||||
}
|
||||
|
||||
CHIAKI_LOGV(stream_connection->log, "StreamConnection received data");
|
||||
CHIAKI_LOGV(stream_connection->log, "StreamConnection received data with msg.type == %d", msg.type);
|
||||
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_VERBOSE, buf, buf_size);
|
||||
|
||||
if(msg.type == tkproto_TakionMessage_PayloadType_DISCONNECT)
|
||||
|
@ -522,7 +559,8 @@ static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *st
|
|||
return;
|
||||
}
|
||||
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection expected bang payload but received something else");
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection expected bang payload but received something else: %d", msg.type);
|
||||
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_VERBOSE, buf, buf_size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -584,6 +622,12 @@ static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *st
|
|||
// stream_connection->state_mutex is expected to be locked by the caller of this function
|
||||
stream_connection->state_finished = true;
|
||||
chiaki_cond_signal(&stream_connection->state_cond);
|
||||
err = stream_connection_send_controller_connection(stream_connection);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection failed to send controller connection");
|
||||
goto error;
|
||||
}
|
||||
return;
|
||||
error:
|
||||
stream_connection->state_failed = true;
|
||||
|
@ -811,6 +855,37 @@ static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream
|
|||
return err;
|
||||
}
|
||||
|
||||
static ChiakiErrorCode stream_connection_send_controller_connection(ChiakiStreamConnection *stream_connection)
|
||||
{
|
||||
ChiakiSession *session = stream_connection->session;
|
||||
tkproto_TakionMessage msg;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
msg.type = tkproto_TakionMessage_PayloadType_CONTROLLERCONNECTION;
|
||||
msg.has_controller_connection_payload = true;
|
||||
msg.controller_connection_payload.has_connected = true;
|
||||
msg.controller_connection_payload.connected = true;
|
||||
msg.controller_connection_payload.has_controller_id = false;
|
||||
msg.controller_connection_payload.has_controller_type = true;
|
||||
msg.controller_connection_payload.controller_type = session->connect_info.enable_dualsense
|
||||
? tkproto_ControllerConnectionPayload_ControllerType_DUALSENSE
|
||||
: tkproto_ControllerConnectionPayload_ControllerType_DUALSHOCK4;
|
||||
|
||||
uint8_t buf[2048];
|
||||
size_t buf_size;
|
||||
|
||||
pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf));
|
||||
bool pbr = pb_encode(&stream, tkproto_TakionMessage_fields, &msg);
|
||||
if(!pbr)
|
||||
{
|
||||
CHIAKI_LOGE(stream_connection->log, "StreamConnection controller connection protobuf encoding failed");
|
||||
return CHIAKI_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
buf_size = stream.bytes_written;
|
||||
return chiaki_takion_send_message_data(&stream_connection->takion, 1, 1, buf, buf_size, NULL);
|
||||
}
|
||||
|
||||
static ChiakiErrorCode stream_connection_send_streaminfo_ack(ChiakiStreamConnection *stream_connection)
|
||||
{
|
||||
tkproto_TakionMessage msg;
|
||||
|
@ -867,6 +942,8 @@ static void stream_connection_takion_av(ChiakiStreamConnection *stream_connectio
|
|||
|
||||
if(packet->is_video)
|
||||
chiaki_video_receiver_av_packet(stream_connection->video_receiver, packet);
|
||||
else if(packet->is_haptics)
|
||||
chiaki_audio_receiver_av_packet(stream_connection->haptics_receiver, packet);
|
||||
else
|
||||
chiaki_audio_receiver_av_packet(stream_connection->audio_receiver, packet);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@ typedef enum takion_packet_type_t {
|
|||
TAKION_PACKET_TYPE_CONGESTION = 5,
|
||||
TAKION_PACKET_TYPE_FEEDBACK_STATE = 6,
|
||||
TAKION_PACKET_TYPE_CLIENT_INFO = 8,
|
||||
TAKION_PACKET_TYPE_PAD_INFO_EVENT = 9
|
||||
TAKION_PACKET_TYPE_PAD_INFO_EVENT = 9,
|
||||
TAKION_PACKET_TYPE_PAD_ADAPTIVE_TRIGGERS = 11,
|
||||
} TakionPacketType;
|
||||
|
||||
/**
|
||||
|
@ -215,6 +216,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, Chiaki
|
|||
takion->postponed_packets = NULL;
|
||||
takion->postponed_packets_size = 0;
|
||||
takion->postponed_packets_count = 0;
|
||||
takion->enable_dualsense = info->enable_dualsense;
|
||||
|
||||
CHIAKI_LOGI(takion->log, "Takion connecting (version %u)", (unsigned int)info->protocol_version);
|
||||
|
||||
|
@ -556,7 +558,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_state(ChiakiTakion *ta
|
|||
else
|
||||
{
|
||||
buf_sz = 0xc + CHIAKI_FEEDBACK_STATE_BUF_SIZE_V12;
|
||||
chiaki_feedback_state_format_v12(buf + 0xc, feedback_state);
|
||||
chiaki_feedback_state_format_v12(buf + 0xc, feedback_state, takion->enable_dualsense);
|
||||
}
|
||||
return takion_send_feedback_packet(takion, buf, buf_sz);
|
||||
}
|
||||
|
@ -950,6 +952,7 @@ static void takion_flush_data_queue(ChiakiTakion *takion)
|
|||
|
||||
if(data_type != CHIAKI_TAKION_MESSAGE_DATA_TYPE_PROTOBUF
|
||||
&& data_type != CHIAKI_TAKION_MESSAGE_DATA_TYPE_RUMBLE
|
||||
&& data_type != CHIAKI_TAKION_MESSAGE_DATA_TYPE_TRIGGER_EFFECTS
|
||||
&& data_type != CHIAKI_TAKION_MESSAGE_DATA_TYPE_9)
|
||||
{
|
||||
CHIAKI_LOGW(takion->log, "Takion received data with unexpected data type %#x", data_type);
|
||||
|
@ -1308,7 +1311,7 @@ static ChiakiErrorCode av_packet_parse(bool v12, ChiakiTakionAVPacket *packet, C
|
|||
|
||||
if(v12 && !packet->is_video)
|
||||
{
|
||||
packet->byte_before_audio_data = *av;
|
||||
packet->is_haptics = *av == 0x02;
|
||||
av += 1;
|
||||
av_size -= 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue