Example #1
0
static bool gamepad_update_device_list(void) {
	int cnt = SDL_NumJoysticks();
	log_info("Updating gamepad devices list");

	if(gamepad.num_devices > 0) {
		assume(gamepad.devices != NULL);

		for(uint i = 0; i < gamepad.num_devices; ++i) {
			SDL_GameControllerClose(gamepad.devices[i].controller);
		}
	}

	gamepad.num_devices = 0;

	if(!cnt) {
		free(gamepad.devices);
		gamepad.devices = NULL;
		gamepad.num_devices_allocated = 0;
		log_info("No joysticks attached");
		return false;
	}

	if(gamepad.num_devices_allocated != cnt) {
		free(gamepad.devices);
		gamepad.devices = calloc(cnt, sizeof(GamepadDevice));
		gamepad.num_devices_allocated = cnt;
	}

	GamepadDevice *dev = gamepad.devices;

	for(int i = 0; i < cnt; ++i) {
		SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(i);
		char guid_str[33] = { 0 };
		SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));

		if(!*guid_str) {
			log_warn("Failed to read GUID of joystick at index %i: %s", i, SDL_GetError());
			continue;
		}

		if(!SDL_IsGameController(i)) {
			log_warn("Joystick at index %i (name: \"%s\"; guid: %s) is not recognized as a game controller by SDL. "
					 "Most likely it just doesn't have a mapping. See https://git.io/vdvdV for solutions",
				i, SDL_JoystickNameForIndex(i), guid_str);
			continue;
		}

		dev->sdl_id = i;
		dev->controller = SDL_GameControllerOpen(i);

		if(dev->controller == NULL) {
			log_sdl_error(LOG_WARN, "SDL_GameControllerOpen");
			continue;
		}

		dev->joy_instance = SDL_JoystickGetDeviceInstanceID(i);

		if(dev->joy_instance < 0) {
			log_sdl_error(LOG_WARN, "SDL_JoystickGetDeviceInstanceID");
			continue;
		}

		log_info("Found device '%s' (#%i): %s", guid_str, DEVNUM(dev), gamepad_device_name_unmapped(i));

		++gamepad.num_devices;
		++dev;
	}

	if(!gamepad.num_devices) {
		log_info("No usable devices");
		return false;
	}

	return true;
}
Example #2
0
/*
 * Open a joystick for use - the index passed as an argument refers to
 * the N'th joystick on the system.  This index is the value which will
 * identify this joystick in future joystick events.
 *
 * This function returns a joystick identifier, or NULL if an error occurred.
 */
SDL_Joystick *
SDL_JoystickOpen(int device_index)
{
    SDL_Joystick *joystick;
    SDL_Joystick *joysticklist;
    const char *joystickname = NULL;

    if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
        SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
        return (NULL);
    }

    SDL_LockJoystickList();

    joysticklist = SDL_joysticks;
    /* If the joystick is already open, return it
     * it is important that we have a single joystick * for each instance id
     */
    while (joysticklist) {
        if (SDL_JoystickGetDeviceInstanceID(device_index) == joysticklist->instance_id) {
                joystick = joysticklist;
                ++joystick->ref_count;
                SDL_UnlockJoystickList();
                return (joystick);
        }
        joysticklist = joysticklist->next;
    }

    /* Create and initialize the joystick */
    joystick = (SDL_Joystick *) SDL_calloc(sizeof(*joystick), 1);
    if (joystick == NULL) {
        SDL_OutOfMemory();
        SDL_UnlockJoystickList();
        return NULL;
    }

    if (SDL_SYS_JoystickOpen(joystick, device_index) < 0) {
        SDL_free(joystick);
        SDL_UnlockJoystickList();
        return NULL;
    }

    joystickname = SDL_SYS_JoystickNameForDeviceIndex(device_index);
    if (joystickname)
        joystick->name = SDL_strdup(joystickname);
    else
        joystick->name = NULL;

    if (joystick->naxes > 0) {
        joystick->axes = (SDL_JoystickAxisInfo *) SDL_calloc(joystick->naxes, sizeof(SDL_JoystickAxisInfo));
    }
    if (joystick->nhats > 0) {
        joystick->hats = (Uint8 *) SDL_calloc(joystick->nhats, sizeof(Uint8));
    }
    if (joystick->nballs > 0) {
        joystick->balls = (struct balldelta *) SDL_calloc(joystick->nballs, sizeof(*joystick->balls));
    }
    if (joystick->nbuttons > 0) {
        joystick->buttons = (Uint8 *) SDL_calloc(joystick->nbuttons, sizeof(Uint8));
    }
    if (((joystick->naxes > 0) && !joystick->axes)
        || ((joystick->nhats > 0) && !joystick->hats)
        || ((joystick->nballs > 0) && !joystick->balls)
        || ((joystick->nbuttons > 0) && !joystick->buttons)) {
        SDL_OutOfMemory();
        SDL_JoystickClose(joystick);
        SDL_UnlockJoystickList();
        return NULL;
    }
    joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;

    /* If this joystick is known to have all zero centered axes, skip the auto-centering code */
    if (SDL_JoystickAxesCenteredAtZero(joystick)) {
        int i;

        for (i = 0; i < joystick->naxes; ++i) {
            joystick->axes[i].has_initial_value = SDL_TRUE;
        }
    }

    joystick->is_game_controller = SDL_IsGameController(device_index);

    /* Add joystick to list */
    ++joystick->ref_count;
    /* Link the joystick in the list */
    joystick->next = SDL_joysticks;
    SDL_joysticks = joystick;

    SDL_UnlockJoystickList();

    SDL_SYS_JoystickUpdate(joystick);

    return (joystick);
}