flutter_input_sdl

English | 中文


English

Introduction

flutter_input_sdl is a Flutter plugin that provides low-level input handling using SDL2 via FFI (Foreign Function Interface). It allows your Flutter application to directly access gamepads, joysticks, and keyboard inputs, bypassing some system-level limitations and providing unified access to a wide range of input devices.

This plugin is designed solely for Input handling. It uses SDL2's mature input subsystem to support GameController mappings (Xbox, PS4/5, Switch Pro, etc.) and raw Joystick data.

Features

  • Gamepad/Joystick Support: Detect, list, and open multiple gamepads or joysticks.
  • Unified Mapping: Uses SDL's GameControllerDB to map various controllers to a standard layout (Ax, By, Start, Back, etc.).
  • Raw Input: Access raw axis and button data.
  • Hot-plugging: Detect device connection and disconnection in real-time.
  • Rumble/Haptics: Support for controller vibration feedback.
  • Keyboard Input: robust keyboard state detection.
  • Cross-Platform: Works on Android, iOS, macOS, Windows, and Linux.

Supported Platforms

  • Android (requires libsdl_input_bridge.so)
  • iOS
  • macOS
  • Windows
  • Linux

Usage

1. Initialization

You must initialize the SDL subsystem before using it.

import 'package:flutter_input_sdl/flutter_input_sdl.dart';

final sdlInput = SdlInput.instance;
await sdlInput.init();

2. Listing Devices

Get a list of currently connected devices.

final devices = sdlInput.getJoysticks();
for (var device in devices) {
  print('${device.name} (Index: ${device.deviceIndex}, IsController: ${device.isGameController})');
}

3. Opening a Device

to read input, you must "open" the device to get an instance ID.

int instanceId = sdlInput.openGameController(0); // Open device at index 0
if (instanceId < 0) {
  // Failed to open
}

4. Handling Events

Listen to the event stream for real-time input.

sdlInput.joystickEvents.listen((event) {
  if (event.type == SDL_INPUT_EVENT_BUTTON_DOWN) {
    print('Button ${event.index} pressed on Instance ${event.instanceId}');
  } else if (event.type == SDL_INPUT_EVENT_AXIS_MOTION) {
    print('Axis ${event.index} moved to ${event.value}');
  }
});

// Don't forget to poll events in your game loop or timer!
Timer.periodic(const Duration(milliseconds: 16), (_) {
  sdlInput.update();
});

5. Rumble

Trigger vibration on the controller.

// Low freq, High freq, Duration (ms)
sdlInput.rumble(instanceId, 0xFFFF, 0xFFFF, 500); 

API Reference

SdlInput Class

Method Description
init() Initialize the SDL input subsystem. Returns Future<bool>.
shutdown() Shutdown and clean up resources.
getJoysticks() Returns List<SdlJoystickInfo> of all connected devices.
openJoystick(index) Open device as a raw joystick. Returns instanceId.
openGameController(index) Open device as a Gamepad (mapped). Returns instanceId.
closeJoystick(instanceId) Close the specific device instance.
rumble(...) Trigger vibration.
update() Polls for new events from the native side. Must be called periodically.
joystickEvents Stream of SdlJoystickEvent.

Libraries

flutter_input_sdl
Flutter SDL2 Input Plugin