Tuesday, April 1, 2008

Intro to SDL with Haskell

So for awhile now I've been working on the lazyfoo tutorials using Haskell's SDL bindings.

I thought it might not be a bad idea to throw up some of the final code. Now one caveat is that I'm going to assume that if you're playing along at home that you have downloaded any materials needed for the tutorial and have it in the same directory as the executable that you're running.

I'll skip tutorial 1 because it's a little too trivial, but below is the code for the second tutorial.

> import Prelude
> import Graphics.UI.SDL as SDL

> background = "background.bmp"
> hello = "hello_world.bmp"

> main = do

The first thing we have to do is initialize the SDL subsystems. For simplicity,
I always just do init [InitEverything].

> SDL.init [InitEverything]

Next, we create a small, vanilla, window using setVideoMode

> setVideoMode 640 480 32 []

Since the images are just bitmaps, we can just use the straight up loadBMP functions.
loadBMP returns a surface, which is the fundamental unit for drawing in SDL.

> image <- loadBMP hello
> back <- loadBMP background

Next we need to grab the surface that we want to draw to.

> screen <- getVideoSurface

And the two blitSurface commands to actually paint the contents of one surface
onto another. The arguments are the source surface, the clipping rectangle of
this surface, the target surface, and the rectangle to which you want to paint.
In both cases, Nothing represents the entire surface. That's why when painting
the background both rectangles are Nothing.

> blitSurface back Nothing screen Nothing
> blitSurface image Nothing screen (Just (Rect 180 140 0 0))

Finally, we need to actually draw the surface on the screen using flip.

> SDL.flip screen

The following function uses events to make sure that the window will stay open
until you choose to close it.

> quitHandler

> quitHandler :: IO ()
> quitHandler = do
> e <- waitEvent
> case e of
> Quit -> return ()
> otherwise -> quitHandler


BMeph said...

In the interests of interestedness...

Er, could you make your borders a little less wide? Or turn on word wrapping? Or otherwise edit your blog so that most of the lines are not cut off in mid-word? Pretty please?

Anonymous said...

What blackmeph said. Your blog didn't handle the "pre" block very well.

Creighton Hogg said...

Wow, yeah, not sure what happened there. I should probably also actually post the rest of the haskell translations I wrote & maybe some of the small games.

Anonymous said...

Hey im having trouble installing the haskell sdl binding im running it by doing runhaskell Setup configure which runs without complaining then i runhaskell Setup build and i get loads of errors about files not excisting and about the SDL things being undeclared. any help would be greatly appreciated

Kurt said...

Thanks for the introduction. I've gotten Lazy Foo' tutorials 1-7 running in Haskell. Tutorial 8 is the first to have a non-trivial event loop and I'm stuck. I'm not sure how to do this in Haskell.. Any suggestions or example code? Thanks

snk_kid said...

You can find all 36 lessons of LazyFoo's SDL tutorials ported to Haskell here.

Anonymous said...

Thank you, this example is very helpful!
Since cabal won't install SDL2 on my system (complaining about versions)
it's very fortunate that at least SDL 1.2 works!

Unfortunately the link to the LazyFoo turorials ported to Haskell appears to be broken.