diff --git a/src/app/input/app_input.c b/src/app/input/app_input.c index bbdbae6f8..bcf7621ee 100644 --- a/src/app/input/app_input.c +++ b/src/app/input/app_input.c @@ -12,7 +12,10 @@ void app_input_init(app_input_t *input, app_t *app) { SDL_SetHint(SDL_HINT_GAMECONTROLLERCONFIG_FILE, app->settings.condb_path); #endif } - SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC); + SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); + input->max_num_gamepads = 4; + input->gamepads_count = 0; + input->activeGamepadMask = 0; input->blank_cursor_surface = SDL_CreateRGBSurface(0, 16, 16, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); input->blank_cursor_surface->userdata = SDL_CreateColorCursor(input->blank_cursor_surface, 0, 0); if (input->blank_cursor_surface->userdata == NULL) { @@ -30,7 +33,7 @@ void app_input_deinit(app_input_t *input) { SDL_FreeCursor(input->blank_cursor_surface->userdata); } SDL_FreeSurface(input->blank_cursor_surface); - SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC); + SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); } void app_set_mouse_grab(app_input_t *input, bool grab) { diff --git a/src/app/input/app_input.h b/src/app/input/app_input.h index f1bc2b394..3e1084dc5 100644 --- a/src/app/input/app_input.h +++ b/src/app/input/app_input.h @@ -28,7 +28,8 @@ typedef struct app_gamepad_state_t { typedef struct app_input_t { commons_gcdb_updater_t gcdb_updater; SDL_Surface *blank_cursor_surface; - app_gamepad_state_t gamepads[4]; + size_t max_num_gamepads; + app_gamepad_state_t gamepads[16]; size_t gamepads_count; short activeGamepadMask; } app_input_t; diff --git a/src/app/input/input_gamepad.c b/src/app/input/input_gamepad.c index 7c9574336..81393a738 100644 --- a/src/app/input/input_gamepad.c +++ b/src/app/input/input_gamepad.c @@ -45,8 +45,7 @@ bool app_input_init_gamepad(app_input_t *input, int which) { state->haptic_effect_id = -1; #endif commons_log_info("Input", "Controller #%d (%s) connected, sdl_id: %d, GUID: %s", state->id, - SDL_JoystickName(joystick), - sdl_id, guidstr); + SDL_JoystickName(joystick), sdl_id, guidstr); input->gamepads_count++; return true; } else { @@ -87,7 +86,7 @@ bool absinput_gamepad_known(app_input_t *input, SDL_JoystickID sdl_id) { } app_gamepad_state_t *app_input_gamepad_get(app_input_t *input, SDL_JoystickID sdl_id) { - for (short i = 0; i < 4; i++) { + for (short i = 0; i < input->max_num_gamepads; i++) { app_gamepad_state_t *gamepad = &input->gamepads[i]; if (!input->gamepads[i].initialized) { input->gamepads[i].sdl_id = sdl_id; @@ -107,7 +106,7 @@ int app_input_gamepads(app_input_t *input) { } int app_input_max_gamepads(app_input_t *input) { - return 4; + return input->max_num_gamepads; } int app_input_gamepads_mask(app_input_t *input) { @@ -184,8 +183,10 @@ void app_input_gamepad_set_motion_event_state(app_input_t *input, unsigned short if (sensor_type == SDL_SENSOR_INVALID) { return; } - SDL_GameControllerSetSensorEnabled(input->gamepads[controllerNumber].controller, sensor_type, - reportRateHz != 0 ? SDL_TRUE : SDL_FALSE); + SDL_GameController *controller = input->gamepads[controllerNumber].controller; + SDL_GameControllerSetSensorEnabled(controller, sensor_type, reportRateHz > 0 ? SDL_TRUE : SDL_FALSE); + commons_log_info("Input", "Setting motion event state for controller %d, motionType: %d, reportRateHz: %d", + controllerNumber, motionType, reportRateHz); #endif } diff --git a/src/app/lvgl/input/lv_drv_sdl_key.c b/src/app/lvgl/input/lv_drv_sdl_key.c index 845dd8936..0f8fc8e4d 100644 --- a/src/app/lvgl/input/lv_drv_sdl_key.c +++ b/src/app/lvgl/input/lv_drv_sdl_key.c @@ -93,6 +93,11 @@ static void sdl_input_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { } } data->continue_reading = true; + } else if (SDL_PeepEvents(&e, 1, SDL_GETEVENT, SDL_CONTROLLERTOUCHPADDOWN, SDL_CONTROLLERSENSORUPDATE) > 0) { + if (app->session != NULL) { + session_handle_input_event(app->session, &e); + } + data->continue_reading = true; } else { data->continue_reading = false; } diff --git a/src/app/stream/input/session_gamepad.c b/src/app/stream/input/session_gamepad.c index 361408368..02645bc1d 100644 --- a/src/app/stream/input/session_gamepad.c +++ b/src/app/stream/input/session_gamepad.c @@ -9,6 +9,7 @@ #include "input/input_gamepad.h" #include "stream/session.h" #include "stream/input/session_virt_mouse.h" +#include "logging.h" #define QUIT_BUTTONS (PLAY_FLAG | BACK_FLAG | LB_FLAG | RB_FLAG) #define GAMEPAD_COMBO_VMOUSE (LB_FLAG | RS_CLK_FLAG) @@ -20,6 +21,7 @@ static void release_buttons(stream_input_t *input, app_gamepad_state_t *gamepad) static bool gamepad_combo_check(int buttons, short combo); + void stream_input_handle_cbutton(stream_input_t *input, const SDL_ControllerButtonEvent *event) { int button = 0; app_gamepad_state_t *gamepad = app_input_gamepad_get(input->input, event->which); @@ -244,8 +246,14 @@ void stream_input_handle_cdevice(stream_input_t *input, const SDL_ControllerDevi if (input->view_only) { return; } + stream_input_send_gamepad_arrive(input, gamepad); +} + +void stream_input_send_gamepad_arrive(const stream_input_t *input, app_gamepad_state_t *gamepad) { uint8_t type = LI_CTYPE_XBOX; uint16_t capabilities = LI_CCAP_ANALOG_TRIGGERS; + commons_log_info("Input", "Controller %d arrived. Name: %s", gamepad->id, + SDL_GameControllerName(gamepad->controller)); switch (SDL_GameControllerGetType(gamepad->controller)) { #if SDL_VERSION_ATLEAST(2, 24, 0) case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: @@ -265,6 +273,7 @@ void stream_input_handle_cdevice(stream_input_t *input, const SDL_ControllerDevi case SDL_CONTROLLER_TYPE_PS5: { type = LI_CTYPE_PS; capabilities |= LI_CCAP_TOUCHPAD; + commons_log_info("Input", " controller capability: touchpad"); break; } default: { @@ -274,25 +283,30 @@ void stream_input_handle_cdevice(stream_input_t *input, const SDL_ControllerDevi #if SDL_VERSION_ATLEAST(2, 0, 18) if (SDL_GameControllerHasRumble(gamepad->controller)) { capabilities |= LI_CCAP_RUMBLE; + commons_log_info("Input", " controller capability: rumble"); } if (SDL_GameControllerHasRumbleTriggers(gamepad->controller)) { capabilities |= LI_CCAP_TRIGGER_RUMBLE; + commons_log_info("Input", " controller capability: trigger rumble"); } #else capabilities |= LI_CCAP_RUMBLE; #if SDL_VERSION_ATLEAST(2, 0, 14) - capabilities |= LI_CCAP_TRIGGER_RUMBLE; + capabilities |= LI_CCAP_TRIGGER_RUMBLE; #endif #endif #if SDL_VERSION_ATLEAST(2, 0, 14) if (SDL_GameControllerHasSensor(gamepad->controller, SDL_SENSOR_ACCEL)) { capabilities |= LI_CCAP_ACCEL; + commons_log_info("Input", " controller capability: accelerometer"); } if (SDL_GameControllerHasSensor(gamepad->controller, SDL_SENSOR_GYRO)) { capabilities |= LI_CCAP_GYRO; + commons_log_info("Input", " controller capability: gyroscope"); } if (SDL_GameControllerHasLED(gamepad->controller)) { capabilities |= LI_CCAP_RGB_LED; + commons_log_info("Input", " controller capability: RGB LED"); } #endif LiSendControllerArrivalEvent(gamepad->id, input->input->activeGamepadMask, type, 0xFFFFFFFF, capabilities); diff --git a/src/app/stream/input/session_input.c b/src/app/stream/input/session_input.c index b28bce411..bb4175fea 100644 --- a/src/app/stream/input/session_input.c +++ b/src/app/stream/input/session_input.c @@ -43,4 +43,15 @@ void session_input_interrupt(stream_input_t *input) { #if FEATURE_INPUT_EVMOUSE session_evmouse_interrupt(&input->evmouse); #endif -} \ No newline at end of file +} + +void session_input_started(stream_input_t *input) { + input->started = true; + for (int i = 0, j = app_input_gamepads(input->input); i < j; ++i) { + stream_input_send_gamepad_arrive(input, app_input_gamepad_get(input->input, i)); + } +} + +void session_input_stopped(stream_input_t *input) { + input->started = false; +} diff --git a/src/app/stream/input/session_input.h b/src/app/stream/input/session_input.h index b440f4085..bdd80a3ab 100644 --- a/src/app/stream/input/session_input.h +++ b/src/app/stream/input/session_input.h @@ -6,6 +6,7 @@ #include #include "config.h" +#include "input/input_gamepad.h" #if FEATURE_INPUT_EVMOUSE @@ -46,6 +47,12 @@ void session_input_deinit(stream_input_t *input); void session_input_interrupt(stream_input_t *input); +void session_input_started(stream_input_t *input); + +void session_input_stopped(stream_input_t *input); + +void stream_input_send_gamepad_arrive(const stream_input_t *input, app_gamepad_state_t *gamepad); + void stream_input_handle_key(stream_input_t *input, const SDL_KeyboardEvent *event); void stream_input_handle_text(stream_input_t *input, const SDL_TextInputEvent *event); diff --git a/src/app/stream/session.c b/src/app/stream/session.c index c899b07ca..69d37fb36 100644 --- a/src/app/stream/session.c +++ b/src/app/stream/session.c @@ -110,11 +110,11 @@ bool session_accepting_input(session_t *session) { } void session_start_input(session_t *session) { - session->input.started = true; + session_input_started(&session->input); } void session_stop_input(session_t *session) { - session->input.started = false; + session_input_stopped(&session->input); } void session_toggle_vmouse(session_t *session) {