diff --git a/gui/src/streamsession.cpp b/gui/src/streamsession.cpp index 89eb72a..7efbe60 100644 --- a/gui/src/streamsession.cpp +++ b/gui/src/streamsession.cpp @@ -123,6 +123,8 @@ void StreamSession::UpdateGamepads() connect(gamepad, &QGamepad::buttonDownChanged, this, &StreamSession::SendFeedbackState); connect(gamepad, &QGamepad::buttonL1Changed, this, &StreamSession::SendFeedbackState); connect(gamepad, &QGamepad::buttonR1Changed, this, &StreamSession::SendFeedbackState); + connect(gamepad, &QGamepad::buttonL1Changed, this, &StreamSession::SendFeedbackState); + connect(gamepad, &QGamepad::buttonL2Changed, this, &StreamSession::SendFeedbackState); connect(gamepad, &QGamepad::buttonL3Changed, this, &StreamSession::SendFeedbackState); connect(gamepad, &QGamepad::buttonR3Changed, this, &StreamSession::SendFeedbackState); connect(gamepad, &QGamepad::buttonStartChanged, this, &StreamSession::SendFeedbackState); @@ -159,6 +161,8 @@ void StreamSession::SendFeedbackState() state.buttons |= gamepad->buttonStart() ? CHIAKI_CONTROLLER_BUTTON_OPTIONS : 0; state.buttons |= gamepad->buttonSelect() ? CHIAKI_CONTROLLER_BUTTON_SHARE : 0; state.buttons |= gamepad->buttonGuide() ? CHIAKI_CONTROLLER_BUTTON_PS : 0; + state.l2_state = (uint8_t)(gamepad->buttonL2() * 0xff); + state.r2_state = (uint8_t)(gamepad->buttonR2() * 0xff); state.left_x = static_cast(gamepad->axisLeftX() * 0x7fff); state.left_y = static_cast(gamepad->axisLeftY() * 0x7fff); state.right_x = static_cast(gamepad->axisRightX() * 0x7fff); diff --git a/lib/include/chiaki/controller.h b/lib/include/chiaki/controller.h index edb3e4b..4b744ac 100644 --- a/lib/include/chiaki/controller.h +++ b/lib/include/chiaki/controller.h @@ -49,6 +49,13 @@ typedef enum chiaki_controller_button_t #define CHIAKI_CONTROLLER_BUTTONS_COUNT 16 +typedef enum chiaki_controller_analog_button_t +{ + // must not overlap with ChiakiControllerButton + CHIAKI_CONTROLLER_ANALOG_BUTTON_L2 = (1 << 16), + CHIAKI_CONTROLLER_ANALOG_BUTTON_R2 = (1 << 17) +} ChiakiControllerAnalogButton; + typedef struct chiaki_controller_state_t { /** @@ -70,6 +77,8 @@ CHIAKI_EXPORT void chiaki_controller_state_set_idle(ChiakiControllerState *state static inline bool chiaki_controller_state_equals(ChiakiControllerState *a, ChiakiControllerState *b) { return a->buttons == b->buttons + && a->l2_state == b->l2_state + && a->r2_state == b->r2_state && a->left_x == b->left_x && a->left_y == b->left_y && a->right_x == b->right_x diff --git a/lib/include/chiaki/feedback.h b/lib/include/chiaki/feedback.h index 91009db..6a74ae1 100644 --- a/lib/include/chiaki/feedback.h +++ b/lib/include/chiaki/feedback.h @@ -53,9 +53,10 @@ typedef struct chiaki_feedback_history_event_t } ChiakiFeedbackHistoryEvent; /** + * @param button ChiakiControllerButton or ChiakiControllerAnalogButton * @param state 0x0 for not pressed, 0xff for pressed, intermediate values for analog triggers */ -CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFeedbackHistoryEvent *event, ChiakiControllerButton button, uint8_t state); +CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFeedbackHistoryEvent *event, uint64_t button, uint8_t state); /** * Ring buffer of ChiakiFeedbackHistoryEvent diff --git a/lib/src/feedback.c b/lib/src/feedback.c index 243ad4d..25dd557 100644 --- a/lib/src/feedback.c +++ b/lib/src/feedback.c @@ -46,7 +46,7 @@ CHIAKI_EXPORT void chiaki_feedback_state_format(uint8_t *buf, ChiakiFeedbackStat *((uint16_t *)(buf + 0x17)) = htons((uint16_t)state->right_y); } -CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFeedbackHistoryEvent *event, ChiakiControllerButton button, uint8_t state) +CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFeedbackHistoryEvent *event, uint64_t button, uint8_t state) { // some buttons use a third byte for the state, some don't event->buf[0] = 0x80; @@ -60,10 +60,10 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFee event->buf[1] = 0x89; break; case CHIAKI_CONTROLLER_BUTTON_BOX: - event->buf[1] = 0x8a; + event->buf[1] = 0x8b; break; case CHIAKI_CONTROLLER_BUTTON_PYRAMID: - event->buf[1] = 0x8b; + event->buf[1] = 0x8a; break; case CHIAKI_CONTROLLER_BUTTON_DPAD_LEFT: event->buf[1] = 0x82; @@ -83,6 +83,12 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFee case CHIAKI_CONTROLLER_BUTTON_R1: event->buf[1] = 0x85; break; + case CHIAKI_CONTROLLER_ANALOG_BUTTON_L2: + event->buf[1] = 0x86; + break; + case CHIAKI_CONTROLLER_ANALOG_BUTTON_R2: + event->buf[1] = 0x87; + break; case CHIAKI_CONTROLLER_BUTTON_L3: event->buf[1] = state ? 0xaf : 0x8f; return CHIAKI_ERR_SUCCESS; diff --git a/lib/src/feedbacksender.c b/lib/src/feedbacksender.c index 6a50243..9f1c455 100644 --- a/lib/src/feedbacksender.c +++ b/lib/src/feedbacksender.c @@ -116,15 +116,19 @@ static void feedback_sender_send_state(ChiakiFeedbackSender *feedback_sender) static bool controller_state_equals_for_feedback_history(ChiakiControllerState *a, ChiakiControllerState *b) { - return a->buttons == b->buttons; + return a->buttons == b->buttons + && a->l2_state == b->l2_state + && a->r2_state == b->r2_state; } static void feedback_sender_send_history(ChiakiFeedbackSender *feedback_sender) { // TODO: Is it legal to have more than one new event per packet? size_t new_events_count = 0; - uint64_t buttons_prev = feedback_sender->controller_state_prev.buttons; - uint64_t buttons_now = feedback_sender->controller_state.buttons; + ChiakiControllerState *state_prev = &feedback_sender->controller_state_prev; + ChiakiControllerState *state_now = &feedback_sender->controller_state; + uint64_t buttons_prev = state_prev->buttons; + uint64_t buttons_now = state_now->buttons; for(uint8_t i=0; il2_state != state_now->l2_state) + { + ChiakiFeedbackHistoryEvent event; + ChiakiErrorCode err = chiaki_feedback_history_event_set_button(&event, CHIAKI_CONTROLLER_ANALOG_BUTTON_L2, state_now->l2_state); + if(err == CHIAKI_ERR_SUCCESS) + { + chiaki_feedback_history_buffer_push(&feedback_sender->history_buf, &event); + new_events_count++; + } + else + CHIAKI_LOGE(feedback_sender->log, "Feedback Sender failed to format button history event for L2\n"); + } + + if(state_prev->r2_state != state_now->r2_state) + { + ChiakiFeedbackHistoryEvent event; + ChiakiErrorCode err = chiaki_feedback_history_event_set_button(&event, CHIAKI_CONTROLLER_ANALOG_BUTTON_R2, state_now->r2_state); + if(err == CHIAKI_ERR_SUCCESS) + { + chiaki_feedback_history_buffer_push(&feedback_sender->history_buf, &event); + new_events_count++; + } + else + CHIAKI_LOGE(feedback_sender->log, "Feedback Sender failed to format button history event for R2\n"); + } + if(!new_events_count) // TODO: also send on timeout sometimes? return;