diff --git a/doc/040_cvarlist.md b/doc/040_cvarlist.md index 013f9d53..a19d0260 100644 --- a/doc/040_cvarlist.md +++ b/doc/040_cvarlist.md @@ -667,12 +667,6 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable` with `1` (default); `0` disables gamepad usage. Can only be set from command line. -* **joy_escbutton**: Defines which button is used in the gamepad as - the `Esc` key, to pull the main menu and 'cancel' / 'go back' on its - options. Valid values are `0` = Start / Menu / Plus (default), `1` = - Back / Select / Minus, or `2` = Guide / Home / PS. Requires a game - restart, or gamepad replug, when changed. - * **joy_labels**: Defines style of button labels in binding menus. Note that binding through console only uses the SDL nomenclature (`0`). Default is `-1`, which requires at least SDL 2.0.12 to work. diff --git a/src/backends/generic/misc.c b/src/backends/generic/misc.c index 54b8f10e..d9acea5a 100644 --- a/src/backends/generic/misc.c +++ b/src/backends/generic/misc.c @@ -108,7 +108,7 @@ static void SetExecutablePath(char* exePath) int name[4] = {CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME}; #endif size_t len = PATH_MAX-1; - int ret = sysctl(name, sizeof(name)/sizeof(name[0]), exePath, &len, NULL, 0); + int ret = sysctl(name, ARRLEN(name), exePath, &len, NULL, 0); if(ret != 0) { // an error occured, clear exe path diff --git a/src/backends/windows/system.c b/src/backends/windows/system.c index 61664166..f5bd10b3 100644 --- a/src/backends/windows/system.c +++ b/src/backends/windows/system.c @@ -622,7 +622,7 @@ Sys_Realpath(const char *in, char *out, size_t size) WCHAR win[MAX_OSPATH] = {0}; WCHAR wconverted[MAX_OSPATH] = {0}; - MultiByteToWideChar(CP_UTF8, 0, in, -1, win, sizeof(win)/sizeof(win[0])); + MultiByteToWideChar(CP_UTF8, 0, in, -1, win, ARRLEN(win)); if (_wfullpath(wconverted, win, size) == NULL) { @@ -706,7 +706,7 @@ Sys_GetWorkDir(char *buffer, size_t len) { WCHAR wbuffer[MAX_OSPATH]; - if (GetCurrentDirectoryW(sizeof(wbuffer)/sizeof(wbuffer[0]), wbuffer) != 0) + if (GetCurrentDirectoryW(ARRLEN(wbuffer), wbuffer) != 0) { WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, len, NULL, NULL); return; @@ -720,7 +720,7 @@ Sys_SetWorkDir(char *path) { WCHAR wpath[MAX_OSPATH]; - MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, sizeof(wpath)/sizeof(wpath[0])); + MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, ARRLEN(wpath)); if (SetCurrentDirectoryW(wpath) != 0) { @@ -760,8 +760,8 @@ Sys_RedirectStdout(void) snprintf(path_stdout, sizeof(path_stdout), "%s/%s", dir, "stdout.txt"); snprintf(path_stderr, sizeof(path_stderr), "%s/%s", dir, "stderr.txt"); - MultiByteToWideChar(CP_UTF8, 0, path_stdout, -1, wpath_stdout, sizeof(wpath_stdout)/sizeof(wpath_stdout[0])); - MultiByteToWideChar(CP_UTF8, 0, path_stderr, -1, wpath_stderr, sizeof(wpath_stderr)/sizeof( wpath_stderr[0] ) ); + MultiByteToWideChar(CP_UTF8, 0, path_stdout, -1, wpath_stdout, ARRLEN(wpath_stdout)); + MultiByteToWideChar(CP_UTF8, 0, path_stderr, -1, wpath_stderr, ARRLEN(wpath_stderr)); _wfreopen(wpath_stdout, L"w", stdout); _wfreopen(wpath_stderr, L"w", stderr); diff --git a/src/client/cl_keyboard.c b/src/client/cl_keyboard.c index fef1d9ff..1a112cdb 100644 --- a/src/client/cl_keyboard.c +++ b/src/client/cl_keyboard.c @@ -222,7 +222,7 @@ static char *gamepadbtns[] = "BTN_NORTH", "BTN_BACK", "BTN_GUIDE", - "BTN_START", + "", // START "STICK_LEFT", "STICK_RIGHT", "SHOULDR_LEFT", @@ -251,7 +251,7 @@ static char *gamepadbtns[] = "BTN_NORTH_ALT", "BTN_BACK_ALT", "BTN_GUIDE_ALT", - "BTN_START_ALT", + "", // START ALT "STICK_LEFT_ALT", "STICK_RIGHT_ALT", "SHOULDR_LEFT_ALT", @@ -275,8 +275,6 @@ static char *gamepadbtns[] = "TRIG_RIGHT_ALT" }; -#define NUM_GAMEPAD_BTNS (sizeof gamepadbtns / sizeof gamepadbtns[0]) - static char *gpbtns_face[] = { // Xbox @@ -284,9 +282,9 @@ static char *gpbtns_face[] = "B", "X", "Y", - "VIEW", + "VIEW", // BACK "XBOX", - "MENU", + "", // MENU / START "LS", "RS", "LB", @@ -296,9 +294,9 @@ static char *gpbtns_face[] = "CIRCLE", "SQUARE", "TRIANGLE", - "CREATE", + "CREATE", // SELECT "PS", - "OPTIONS", + "", // OPTIONS / START "L3", "R3", "L1", @@ -310,7 +308,7 @@ static char *gpbtns_face[] = "X", "-", "HOME", - "+", + "", // "+" "L stick", "R stick", "L btn", @@ -822,6 +820,7 @@ Key_Message(int key) static int Key_StringToKeynum(char *str) { + static const int num_gamepad_btns = ARRLEN(gamepadbtns); keyname_t *kn; int i; @@ -843,7 +842,7 @@ Key_StringToKeynum(char *str) } } - for (i = 0; i < NUM_GAMEPAD_BTNS; i++) + for (i = 0; i < num_gamepad_btns; i++) { if (!Q_stricmp(str, gamepadbtns[i])) { diff --git a/src/client/input/sdl2.c b/src/client/input/sdl2.c index 138bd08f..c280a4f4 100644 --- a/src/client/input/sdl2.c +++ b/src/client/input/sdl2.c @@ -93,7 +93,6 @@ typedef enum // IN_Update() called at the beginning of a frame to the // actual movement functions called at a later time. static float mouse_x, mouse_y; -static unsigned char joy_escbutton = SDL_CONTROLLER_BUTTON_START; static int joystick_left_x, joystick_left_y, joystick_right_x, joystick_right_y; static qboolean mlooking; @@ -1049,12 +1048,10 @@ IN_Update(void) case SDL_CONTROLLERBUTTONUP: case SDL_CONTROLLERBUTTONDOWN: { - qboolean down = (event.type == SDL_CONTROLLERBUTTONDOWN); unsigned char btn = event.cbutton.button; - // Handle Esc button first, to override its original key - Key_Event( (btn == joy_escbutton)? K_ESCAPE : K_JOY_FIRST_BTN + btn, - down, true ); + Key_Event( (btn == SDL_CONTROLLER_BUTTON_START)? K_ESCAPE : K_JOY_FIRST_BTN + btn, + (event.type == SDL_CONTROLLERBUTTONDOWN), true ); break; } @@ -2534,44 +2531,136 @@ IN_Haptic_Prepare(void) } /* - * Game Controller + * Helper functions for Gyro initialization. + * Their nature depend on NO_SDL_GYRO. + */ + +#ifndef NO_SDL_GYRO + +static void +IN_Joy_IMU_Treatment(SDL_Joystick *joystick, const char* joystick_name, int joy_num) +{ + SDL_JoystickClose(joystick); + joystick = NULL; + Com_Printf ("Skipping IMU device.\n"); +} + +static void +IN_Gyro_and_LED_Enabling(void) +{ + if (!controller) return; + + const qboolean found_gyro = + SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) + && !SDL_GameControllerSetSensorEnabled( + controller, SDL_SENSOR_GYRO, SDL_TRUE); + + const qboolean found_accel = + SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) + && !SDL_GameControllerSetSensorEnabled( + controller, SDL_SENSOR_ACCEL, SDL_TRUE); + + if (found_gyro && found_accel) + { + show_gyro = true; +#if SDL_VERSION_ATLEAST(2, 0, 16) + Com_Printf("Sensors enabled: Gyro at %.2f Hz, Accelerometer at %.2f Hz\n", + SDL_GameControllerGetSensorDataRate(controller, SDL_SENSOR_GYRO), + SDL_GameControllerGetSensorDataRate(controller, SDL_SENSOR_ACCEL)); +#else + Com_Printf("Gyro and accelerometer sensors enabled.\n"); +#endif // #if SDL_VERSION_ATLEAST(2, 0, 16) + } + else + { + if (!found_gyro) + { + Com_Printf("Gyro sensor not found.\n"); + } + + if (!found_accel) + { + Com_Printf("Accelerometer sensor not found.\n"); + } + + // Both were required for gyro support, so disable them completely. + SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_FALSE); + SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_FALSE); + } + + if ( SDL_GameControllerHasLED(controller) ) + { + SDL_GameControllerSetLED(controller, 0, 80, 0); // green light + } +} + +static qboolean +IN_GameController_Verify_Init_Complete(void) +{ + return show_gamepad; +} + +#else // with NO_SDL_GYRO + +static void +IN_Joy_IMU_Treatment(SDL_Joystick *joystick, const char* joystick_name, int joy_num) +{ + // If it's not a Left JoyCon, use it as Gyro + const qboolean using_imu = !imu_joystick && + !( strstr(joystick_name, "Joy-Con") && strstr(joystick_name, "L") ); + Com_Printf ("IMU device found... "); + SDL_JoystickClose(joystick); + joystick = NULL; + + if (using_imu) + { + imu_joystick = SDL_JoystickOpen(joy_num); + if (imu_joystick) + { + show_gyro = true; + Com_Printf ("using it as Gyro sensor.\n"); + } + else + { + Com_Printf ("\nCouldn't open IMU: %s.\n", SDL_GetError()); + } + } + else + { + Com_Printf ("skipping.\n"); + } +} + +static void +IN_Gyro_and_LED_Enabling(void) +{ + // Unavailable in this case +} + +static qboolean +IN_GameController_Verify_Init_Complete(void) +{ + return (show_gamepad && show_gyro); +} + +#endif // NO_SDL_GYRO + +/* + * Game Controller initialization */ static void IN_Controller_Init(qboolean notify_user) { - cvar_t *cvar; - int nummappings, numjoysticks, joy_num, i; + int numjoysticks, joy_num, i; char controllerdb[MAX_OSPATH] = {0}; SDL_Joystick *joystick = NULL; SDL_bool is_controller = SDL_FALSE; - cvar = Cvar_Get("joy_escbutton", "0", CVAR_ARCHIVE); - if (cvar) - { - switch ((int)cvar->value) - { - case 1: - joy_escbutton = SDL_CONTROLLER_BUTTON_BACK; - break; - case 2: - joy_escbutton = SDL_CONTROLLER_BUTTON_GUIDE; - break; - default: - joy_escbutton = SDL_CONTROLLER_BUTTON_START; - } - } - - cvar = Cvar_Get("in_initjoy", "1", CVAR_NOSET); + cvar_t *cvar = Cvar_Get("in_initjoy", "1", CVAR_NOSET); joy_num = (int)cvar->value; - if (joy_num < 1) - { - return; - } + if (joy_num < 1) return; - if (notify_user) - { - Com_Printf("- Game Controller init attempt -\n"); - } + if (notify_user) Com_Printf("- Game Controller init attempt -\n"); if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER)) { @@ -2606,7 +2695,7 @@ IN_Controller_Init(qboolean notify_user) for (const char* rawPath = FS_GetNextRawPath(NULL); rawPath != NULL; rawPath = FS_GetNextRawPath(rawPath)) { snprintf(controllerdb, MAX_OSPATH, "%s/gamecontrollerdb.txt", rawPath); - nummappings = SDL_GameControllerAddMappingsFromFile(controllerdb); + int nummappings = SDL_GameControllerAddMappingsFromFile(controllerdb); if (nummappings > 0) Com_Printf ("%d mappings loaded from gamecontrollerdb.txt\n", nummappings); } @@ -2616,9 +2705,6 @@ IN_Controller_Init(qboolean notify_user) i = joy_num; do { - const char* joystick_name; - size_t name_len; - joystick = SDL_JoystickOpen(i); if (!joystick) { @@ -2626,43 +2712,15 @@ IN_Controller_Init(qboolean notify_user) goto next_joy; // try next joystick } - joystick_name = SDL_JoystickName(joystick); - name_len = strlen(joystick_name); + const char* joystick_name = SDL_JoystickName(joystick); + const size_t name_len = strlen(joystick_name); Com_Printf ("Trying joystick %d, '%s'\n", i+1, joystick_name); // Ugly hack to detect IMU-only devices - works for Switch controllers at least if ( name_len > 6 && strstr(joystick_name + name_len - 6, "IMU") ) { -#ifndef NO_SDL_GYRO - SDL_JoystickClose(joystick); - joystick = NULL; - Com_Printf ("Skipping IMU device.\n"); - -#else // if it's not a Left JoyCon, use it as Gyro - qboolean using_imu = !imu_joystick && !( strstr(joystick_name, "Joy-Con") && strstr(joystick_name, "L") ); - Com_Printf ("IMU device found... "); - SDL_JoystickClose(joystick); - joystick = NULL; - - if (using_imu) - { - imu_joystick = SDL_JoystickOpen(i); - if (imu_joystick) - { - show_gyro = true; - Com_Printf ("using it as Gyro sensor.\n"); - } - else - { - Com_Printf ("\nCouldn't open IMU: %s.\n", SDL_GetError()); - } - } - else - { - Com_Printf ("skipping.\n"); - } -#endif + IN_Joy_IMU_Treatment(joystick, joystick_name, i); goto next_joy; } @@ -2674,7 +2732,6 @@ IN_Controller_Init(qboolean notify_user) { char joystick_guid[65] = {0}; SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(i); - SDL_JoystickGetGUIDString(guid, joystick_guid, 64); Com_Printf ("To use joystick as game controller, provide its config by either:\n" @@ -2684,6 +2741,7 @@ IN_Controller_Init(qboolean notify_user) } SDL_JoystickClose(joystick); + joystick = NULL; if (is_controller && !controller) { @@ -2696,53 +2754,7 @@ IN_Controller_Init(qboolean notify_user) show_gamepad = true; Com_Printf("Enabled as Game Controller, settings:\n%s\n", SDL_GameControllerMapping(controller)); - -#ifndef NO_SDL_GYRO - - const qboolean found_gyro = - SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) - && !SDL_GameControllerSetSensorEnabled( - controller, SDL_SENSOR_GYRO, SDL_TRUE); - - const qboolean found_accel = - SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) - && !SDL_GameControllerSetSensorEnabled( - controller, SDL_SENSOR_ACCEL, SDL_TRUE); - - if (found_gyro && found_accel) - { - show_gyro = true; -#if SDL_VERSION_ATLEAST(2, 0, 16) - Com_Printf("Sensors enabled: Gyro at %.2f Hz, Accelerometer at %.2f Hz\n", - SDL_GameControllerGetSensorDataRate(controller, SDL_SENSOR_GYRO), - SDL_GameControllerGetSensorDataRate(controller, SDL_SENSOR_ACCEL)); -#else - Com_Printf("Gyro and accelerometer sensors enabled.\n"); -#endif // #if SDL_VERSION_ATLEAST(2, 0, 16) - } - else - { - if (!found_gyro) - { - Com_Printf("Gyro sensor not found.\n"); - } - - if (!found_accel) - { - Com_Printf("Accelerometer sensor not found.\n"); - } - - // Both were required for gyro support, so disable them completely. - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_FALSE); - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_FALSE); - } - - if ( SDL_GameControllerHasLED(controller) ) - { - SDL_GameControllerSetLED(controller, 0, 80, 0); // green light - } - -#endif // !NO_SDL_GYRO + IN_Gyro_and_LED_Enabling(); joystick_haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(controller)); IN_Haptic_Prepare(); @@ -2762,13 +2774,10 @@ IN_Controller_Init(qboolean notify_user) { Com_Printf("Controller doesn't support rumble.\n"); } - -#ifndef NO_SDL_GYRO // "native SDL gyro" exits when finding a single working gamepad - break; -#endif } next_joy: + if (IN_GameController_Verify_Init_Complete()) break; i++; if (i == numjoysticks) i = 0; } @@ -2804,7 +2813,7 @@ static const joy_preset_t joy_presets[] = { void IN_ApplyJoyPreset(void) { - const int final_preset = ARRLEN(joy_presets) - 1; + static const int final_preset = ARRLEN(joy_presets) - 1; const int i = lroundf(Q_clamp(joy_sensitivity->value, 0, final_preset)); joy_sensitivity->modified = false; @@ -2822,7 +2831,7 @@ IN_ApplyJoyPreset(void) qboolean IN_MatchJoyPreset(void) { - const int num_presets = ARRLEN(joy_presets); + static const int num_presets = ARRLEN(joy_presets); for (int i = 0; i < num_presets; i++) { diff --git a/src/client/input/sdl3.c b/src/client/input/sdl3.c index 9fce7efb..45ac4311 100644 --- a/src/client/input/sdl3.c +++ b/src/client/input/sdl3.c @@ -96,7 +96,6 @@ typedef enum // IN_Update() called at the beginning of a frame to the // actual movement functions called at a later time. static float mouse_x, mouse_y; -static unsigned char joy_escbutton = SDL_GAMEPAD_BUTTON_START; static int joystick_left_x, joystick_left_y, joystick_right_x, joystick_right_y; static qboolean mlooking; @@ -1030,12 +1029,10 @@ IN_Update(void) case SDL_EVENT_GAMEPAD_BUTTON_UP : case SDL_EVENT_GAMEPAD_BUTTON_DOWN : { - qboolean down = (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); unsigned char btn = event.gbutton.button; - // Handle Esc button first, to override its original key - Key_Event( (btn == joy_escbutton)? K_ESCAPE : K_JOY_FIRST_BTN + btn, - down, true ); + Key_Event( (btn == SDL_GAMEPAD_BUTTON_START)? K_ESCAPE : K_JOY_FIRST_BTN + btn, + (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN), true ); break; } @@ -2515,44 +2512,134 @@ IN_Haptic_Prepare(void) } /* - * Game Controller + * Helper functions for Gyro initialization. + * Their nature depend on NO_SDL_GYRO. + */ + +#ifndef NO_SDL_GYRO + +static void +IN_Joy_IMU_Treatment(SDL_Joystick *joystick, const char* joystick_name, SDL_JoystickID joy_id) +{ + SDL_CloseJoystick(joystick); + joystick = NULL; + Com_Printf ("Skipping IMU device.\n"); +} + +static void +IN_Gyro_and_LED_Enabling(void) +{ + if (!controller) return; + + const qboolean found_gyro = + SDL_GamepadHasSensor(controller, SDL_SENSOR_GYRO) + && SDL_SetGamepadSensorEnabled( + controller, SDL_SENSOR_GYRO, true); + + const qboolean found_accel = + SDL_GamepadHasSensor(controller, SDL_SENSOR_ACCEL) + && SDL_SetGamepadSensorEnabled( + controller, SDL_SENSOR_ACCEL, true); + + if (found_gyro && found_accel) + { + show_gyro = true; + Com_Printf("Sensors enabled: Gyro at %.2f Hz, Accelerometer at %.2f Hz\n", + SDL_GetGamepadSensorDataRate(controller, SDL_SENSOR_GYRO), + SDL_GetGamepadSensorDataRate(controller, SDL_SENSOR_ACCEL)); + } + else + { + if (!found_gyro) + { + Com_Printf("Gyro sensor not found.\n"); + } + + if (!found_accel) + { + Com_Printf("Accelerometer sensor not found.\n"); + } + + // Both were required for gyro support, so disable them completely. + SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, false); + SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, false); + } + + const bool hasLED = SDL_GetBooleanProperty( SDL_GetGamepadProperties(controller), + SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN, false ); + if (hasLED) + { + SDL_SetGamepadLED(controller, 0, 80, 0); // green light + } +} + +static qboolean +IN_GameController_Verify_Init_Complete(void) +{ + return show_gamepad; +} + +#else // with NO_SDL_GYRO + +static void +IN_Joy_IMU_Treatment(SDL_Joystick *joystick, const char* joystick_name, SDL_JoystickID joy_id) +{ + // If it's not a Left JoyCon, use it as Gyro + const qboolean using_imu = !imu_joystick && + !( strstr(joystick_name, "Joy-Con") && strstr(joystick_name, "L") ); + Com_Printf ("IMU device found... "); + SDL_CloseJoystick(joystick); + joystick = NULL; + + if (using_imu) + { + imu_joystick = SDL_OpenJoystick(joy_id); + if (imu_joystick) + { + show_gyro = true; + Com_Printf ("using it as Gyro sensor.\n"); + } + else + { + Com_Printf ("\nCouldn't open IMU: %s.\n", SDL_GetError()); + } + } + else + { + Com_Printf ("skipping.\n"); + } +} + +static void +IN_Gyro_and_LED_Enabling(void) +{ + // Unavailable in this case +} + +static qboolean +IN_GameController_Verify_Init_Complete(void) +{ + return (show_gamepad && show_gyro); +} + +#endif // NO_SDL_GYRO + +/* + * Game Controller initialization */ static void IN_Controller_Init(qboolean notify_user) { - cvar_t *cvar; - int nummappings, numjoysticks, joy_num, i; + int numjoysticks, joy_num, i; char controllerdb[MAX_OSPATH] = {0}; SDL_Joystick *joystick = NULL; bool is_controller = false; - cvar = Cvar_Get("joy_escbutton", "0", CVAR_ARCHIVE); - if (cvar) - { - switch ((int)cvar->value) - { - case 1: - joy_escbutton = SDL_GAMEPAD_BUTTON_BACK; - break; - case 2: - joy_escbutton = SDL_GAMEPAD_BUTTON_GUIDE; - break; - default: - joy_escbutton = SDL_GAMEPAD_BUTTON_START; - } - } - - cvar = Cvar_Get("in_initjoy", "1", CVAR_NOSET); + cvar_t *cvar = Cvar_Get("in_initjoy", "1", CVAR_NOSET); joy_num = (int)cvar->value; - if (joy_num < 1) - { - return; - } + if (joy_num < 1) return; - if (notify_user) - { - Com_Printf("- Gamepad init attempt -\n"); - } + if (notify_user) Com_Printf("- Gamepad init attempt -\n"); if (!SDL_WasInit(SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC)) { @@ -2576,14 +2663,13 @@ IN_Controller_Init(qboolean notify_user) IN_Haptic_Prepare(); SDL_free((void *)joysticks); - return; } for (const char* rawPath = FS_GetNextRawPath(NULL); rawPath != NULL; rawPath = FS_GetNextRawPath(rawPath)) { snprintf(controllerdb, MAX_OSPATH, "%s/gamecontrollerdb.txt", rawPath); - nummappings = SDL_AddGamepadMappingsFromFile(controllerdb); + int nummappings = SDL_AddGamepadMappingsFromFile(controllerdb); if (nummappings > 0) Com_Printf ("%d mappings loaded from gamecontrollerdb.txt\n", nummappings); } @@ -2601,54 +2687,25 @@ IN_Controller_Init(qboolean notify_user) } const char* joystick_name = SDL_GetJoystickName(joystick); - const int name_len = strlen(joystick_name); + const size_t name_len = strlen(joystick_name); Com_Printf ("Trying joystick %d, '%s'\n", i+1, joystick_name); // Ugly hack to detect IMU-only devices - works for Switch controllers at least if ( name_len > 6 && strstr(joystick_name + name_len - 6, "IMU") ) { -#ifndef NO_SDL_GYRO - SDL_CloseJoystick(joystick); - joystick = NULL; - Com_Printf ("Skipping IMU device.\n"); - -#else // if it's not a Left JoyCon, use it as Gyro - qboolean using_imu = !imu_joystick && !( strstr(joystick_name, "Joy-Con") && strstr(joystick_name, "L") ); - Com_Printf ("IMU device found... "); - SDL_CloseJoystick(joystick); - joystick = NULL; - - if (using_imu) - { - imu_joystick = SDL_OpenJoystick(joysticks[i]); - if (imu_joystick) - { - show_gyro = true; - Com_Printf ("using it as Gyro sensor.\n"); - } - else - { - Com_Printf ("\nCouldn't open IMU: %s.\n", SDL_GetError()); - } - } - else - { - Com_Printf ("skipping.\n"); - } -#endif + IN_Joy_IMU_Treatment(joystick, joystick_name, joysticks[i]); goto next_joy; } Com_Printf ("Buttons = %d, Axes = %d, Hats = %d\n", SDL_GetNumJoystickButtons(joystick), - SDL_GetNumJoystickAxes(joystick), SDL_GetNumJoystickHats(joystick)); + SDL_GetNumJoystickAxes(joystick), SDL_GetNumJoystickHats(joystick)); is_controller = SDL_IsGamepad(joysticks[i]); if (!is_controller) { char joystick_guid[65] = {0}; SDL_GUID guid = SDL_GetJoystickGUIDForID(joysticks[i]); - SDL_GUIDToString(guid, joystick_guid, 64); Com_Printf ("To identify joystick as Gamepad, provide its config by either:\n" @@ -2670,57 +2727,14 @@ IN_Controller_Init(qboolean notify_user) } show_gamepad = true; - Com_Printf("Enabled as Gamepad, settings:\n%s\n", - SDL_GetGamepadMapping(controller)); - -#ifndef NO_SDL_GYRO - - const qboolean found_gyro = - SDL_GamepadHasSensor(controller, SDL_SENSOR_GYRO) - && SDL_SetGamepadSensorEnabled( - controller, SDL_SENSOR_GYRO, true); - - const qboolean found_accel = - SDL_GamepadHasSensor(controller, SDL_SENSOR_ACCEL) - && SDL_SetGamepadSensorEnabled( - controller, SDL_SENSOR_ACCEL, true); - - if (found_gyro && found_accel) - { - show_gyro = true; - Com_Printf("Sensors enabled: Gyro at %.2f Hz, Accelerometer at %.2f Hz\n", - SDL_GetGamepadSensorDataRate(controller, SDL_SENSOR_GYRO), - SDL_GetGamepadSensorDataRate(controller, SDL_SENSOR_ACCEL)); - } - else - { - if (!found_gyro) - { - Com_Printf("Gyro sensor not found.\n"); - } - - if (!found_accel) - { - Com_Printf("Accelerometer sensor not found.\n"); - } - - // Both were required for gyro support, so disable them completely. - SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, false); - SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, false); - } - - bool hasLED = SDL_GetBooleanProperty(SDL_GetGamepadProperties(controller), SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN, false); - if (hasLED) - { - SDL_SetGamepadLED(controller, 0, 80, 0); // green light - } - -#endif // !NO_SDL_GYRO + Com_Printf("Enabled as Gamepad, settings:\n%s\n", SDL_GetGamepadMapping(controller)); + IN_Gyro_and_LED_Enabling(); joystick_haptic = SDL_OpenHapticFromJoystick(SDL_GetGamepadJoystick(controller)); IN_Haptic_Prepare(); - bool hasRumble = SDL_GetBooleanProperty(SDL_GetGamepadProperties(controller), SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false); + const bool hasRumble = SDL_GetBooleanProperty( SDL_GetGamepadProperties(controller), + SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, false ); if (hasRumble) { show_haptic = true; @@ -2730,13 +2744,10 @@ IN_Controller_Init(qboolean notify_user) { Com_Printf("Gamepad doesn't support rumble.\n"); } - -#ifndef NO_SDL_GYRO // "native SDL gyro" exits when finding a single working gamepad - break; -#endif } next_joy: + if (IN_GameController_Verify_Init_Complete()) break; i++; if (i == numjoysticks) i = 0; } @@ -2773,7 +2784,7 @@ static const joy_preset_t joy_presets[] = { void IN_ApplyJoyPreset(void) { - const int final_preset = ARRLEN(joy_presets) - 1; + static const int final_preset = ARRLEN(joy_presets) - 1; const int i = lroundf(Q_clamp(joy_sensitivity->value, 0, final_preset)); joy_sensitivity->modified = false; @@ -2791,7 +2802,7 @@ IN_ApplyJoyPreset(void) qboolean IN_MatchJoyPreset(void) { - const int num_presets = ARRLEN(joy_presets); + static const int num_presets = ARRLEN(joy_presets); for (int i = 0; i < num_presets; i++) { diff --git a/src/common/filesystem.c b/src/common/filesystem.c index c74991e1..133d5fae 100644 --- a/src/common/filesystem.c +++ b/src/common/filesystem.c @@ -167,8 +167,7 @@ static voidpf ZCALLBACK fopen_file_func_utf(voidpf opaque, const char *filename, if (!((filename == NULL) || (mode_fopen == NULL))) { - MultiByteToWideChar(CP_UTF8, 0, filename, -1, wfilename, - sizeof(wfilename) / sizeof(*wfilename)); + MultiByteToWideChar(CP_UTF8, 0, filename, -1, wfilename, ARRLEN(wfilename)); file = _wfopen((const wchar_t *) wfilename, mode_fopen); } @@ -1492,7 +1491,7 @@ static int Q_sort_modcmp(const void *p1, const void *p2) { static const char *first_mods[] = {BASEDIRNAME, "xatrix", "rogue", "ctf"}; - static const unsigned short int first_mods_qty = 4; + static const unsigned short int first_mods_qty = ARRLEN(first_mods); const char * s1 = * (char * const *)p1; const char * s2 = * (char * const *)p2; diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index a88e7d05..1dfc7b65 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1104,7 +1104,7 @@ flooded(edict_t *ent) } cl = ent->client; - mx = sizeof(cl->flood_when) / sizeof(cl->flood_when[0]); + mx = ARRLEN(cl->flood_when); if (num_msgs > mx) {