sdl3-cr

Minimal SDL3 FFI binding for Crystal

sdl3-cr

Minimal FFI binding of SDL3 for Crystal — window, events, keyboard, gamepads (SDL_Gamepad), audio, compressed music (SDL3_mixer) and Metal surface. In the spirit of wgpu-cr: a raw binding under the LibSDL namespace (plus LibMIX for SDL3_mixer), functions in snake_case.

Hand-written (not auto-generated) and deliberately reduced to the subset useful to a 2D/3D game engine. Types, structs and function signatures are handwritten in src/sdl3.cr; extend lib LibSDL there as needed.

The numeric constants (INIT_*, WINDOW_*, EVENT_*, AUDIO_*, PIXELFORMAT_RGBA32) are generated into src/sdl3/constants.cr by scripts/generate_constants.cr: it compiles a small probe against the installed SDL3 (pkg-config --cflags sdl3) so the C compiler evaluates every macro (SDL_DEFINE_PIXELFORMAT, bit-shifts, endianness-dependent audio formats, auto-incremented event enums) — no drift, no hand-retyping. Regenerate after an SDL3 upgrade:

shards run sdl3-gen      # or: crystal run scripts/generate_constants.cr

The generated file is checked in, so consumers of the shard need no C compiler.

Prerequisites

brew install sdl3 sdl3_image sdl3_ttf sdl3_mixer   # macOS
# Debian/Ubuntu: apt install libsdl3-dev libsdl3-image-dev libsdl3-ttf-dev libsdl3-mixer-dev

Linking is done via pkg-config (@[Link(pkg_config: "sdl3")], "sdl3-image", "sdl3-ttf", "sdl3-mixer"), portable macOS/Linux (and Windows via vcpkg/msys2 pkg-config). Falls back to -lSDL3* if pkg-config is absent.

Usage

require "sdl3"   # or, without shards install: require "../sdl3-cr/src/sdl3"

abort "SDL_Init" unless LibSDL.init(LibSDL::INIT_VIDEO)
window = LibSDL.create_window("hello", 800, 600, LibSDL::WINDOW_METAL)
# … LibSDL.metal_create_view / metal_get_layer for a wgpu surface, etc.
LibSDL.quit

Consumed by flock (game engine) via a relative require.

Coverage

Init/errors, window + SDL_Metal_CreateView/GetLayer, SDL_PollEvent (type), keyboard (SDL_GetKeyboardState), mouse (SDL_GetMouseState), gamepads (SDL_GetGamepads/ OpenGamepad/GetGamepadButton/GetGamepadAxis/RumbleGamepad, hotplug), audio (SDL_LoadWAV, OpenAudioDeviceStream, streams + gain + mixing), version (SDL_GetVersion), images (IMG_Load, SDL3_image), text (TTF_OpenFont/RenderText_Blended, SDL3_ttf), events (SDL_PollEvent + MouseWheelEvent/TextInputEvent/WindowEvent structs, EVENT_WINDOW_* focus/minimize/maximize/resize constants, SDL_StartTextInput), compressed music (SDL3_mixer 3.x MIX_* in lib LibMIX: MIX_CreateMixerDevice/ MIX_LoadAudio/MIX_CreateTrack/MIX_PlayTrack/loops/gain — OGG/MP3/FLAC/Opus).

Test

crystal spec      # binding + generated-constants sanity (headless)

License

MIT — see LICENSE.

Repository

sdl3-cr

Owner
Statistic
  • 0
  • 0
  • 0
  • 1
  • 0
  • about 7 hours ago
  • August 19, 2026
License

MIT License

Links
Synced at

Wed, 19 Aug 2026 12:18:28 GMT

Languages