sdl2-2.4.0.1: Both high- and low-level bindings to the SDL library (version 2.0.4+).

Safe HaskellNone
LanguageHaskell2010

SDL

Contents

Description

SDL (Simple DirectMedia Layer) is a library for cross-platform development of interactive applications. SDL provides routines for managing windows, rendering graphics, processing sound, collecting input data, and much more. The Haskell sdl2 library provides both a high- and low-level API to interface with SDL. This module exports the high-level API, whereas SDL.Raw provides the lower-level bindings.

Synopsis

Getting Started

The SDL module exports a high-level Haskell-like abstraction to use the SDL library. SDL is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D.

To get started, import SDL and begin by initializing the subsystems you need:

import SDL

main :: IO ()
main = do
  initializeAll

Next, you can create a Window by using createWindow

  window <- createWindow "My SDL Application" defaultWindow

If you wish to use SDL's 2D graphics API, you can also create a Renderer:

  renderer <- createRenderer window (-1) defaultRenderer

Finally, we enter our main application loop:

  appLoop renderer

For the body of your application, we enter a loop. Inside this loop you should begin by collecting all events that have happened - these events will inform you about information such as key presses and mouse movement:

appLoop :: Renderer -> IO ()
appLoop renderer = do
  events <- pollEvents

Here events is a list of Event values. For our application we will check if the user pressed the q key, indicating they wish to quit the application

  let eventIsQPress event =
        case eventPayload event of
          KeyboardEvent keyboardEvent ->
            keyboardEventKeyMotion keyboardEvent == Pressed &&
            keysymKeycode (keyboardEventKeysym keyboardEvent) == KeycodeQ
          _ -> False
      qPressed = any eventIsQPress events

In our appLoop we process events and then update the screen accordingly. Here we simply use the Renderer to clear the screen to blue:

  rendererDrawColor renderer $= V4 0 0 255 255
  clear renderer
  present renderer

If q was not pressed, we loop again. Otherwise, we exit the loop:

  unless qPressed (appLoop renderer)

To recap, here is our full application

{-# LANGUAGE OverloadedStrings #-}
module Main where

import SDL
import Linear (V4(..))
import Control.Monad (unless)

main :: IO ()
main = do
  initializeAll
  window <- createWindow "My SDL Application" defaultWindow
  renderer <- createRenderer window (-1) defaultRenderer
  appLoop renderer

appLoop :: Renderer -> IO ()
appLoop renderer = do
  events <- pollEvents
  let eventIsQPress event =
        case eventPayload event of
          KeyboardEvent keyboardEvent ->
            keyboardEventKeyMotion keyboardEvent == Pressed &&
            keysymKeycode (keyboardEventKeysym keyboardEvent) == KeycodeQ
          _ -> False
      qPressed = any eventIsQPress events
  rendererDrawColor renderer $= V4 0 0 255 255
  clear renderer
  present renderer
  unless qPressed (appLoop renderer)

Initialization

module SDL.Init

Modules

module SDL.Audio

module SDL.Event

module SDL.Hint

module SDL.Input

module SDL.Power

module SDL.Time

module SDL.Vect

module SDL.Video

Error Handling

Working with State Variables

The SDL API is moderately stateful. For the places where there is state that can be both read and changed, we use an abstraction provided by Data.StateVar. This module exposes the StateVar type, which models a mutable variable. You can query the contents of a StateVar with get, and you can replace the contents of StateVar with the infix assignment operator $=.

get :: (HasGetter t a, MonadIO m) => t -> m a #

($=) :: (HasSetter t a, MonadIO m) => t -> a -> m () infixr 2 #

Write a new value into a state variable.

($~) :: (HasUpdate t a b, MonadIO m) => t -> (a -> b) -> m () infixr 2 #

Transform the contents of a state variable with a given funtion.

Strict modification

($=!) :: (HasSetter t a, MonadIO m) => t -> a -> m () infixr 2 #

This is a variant of $= which is strict in the value to be set.

($~!) :: (HasUpdate t a b, MonadIO m) => t -> (a -> b) -> m () infixr 2 #

This is a variant of $~ which is strict in the transformed value.