FFI (その3)

前回までで大体FFIの方法がわかったので、
とりあえずVideoのラッパを作成した。
本当にうすうすなラッパなんだけど…
しかし、ポインタのやり取りが多いのでどうすればいいのか結構悩んだ。
結局Surface以外はStorableなデータとしてあらわすことにした。
Foreign.Marshalな関数とかでごりごりメモリの読み書き。
ああ、なんなんだこれは。
(逆に、Haskell学習当初の印象とは違ってHaskellだけでも
なんでもできるんだなぁとしみじみ…)


で、とりあえず何か適当に作ってみた。
やはりまだEventが使えないのでたいしたことは出来ない。

module Main(main) where

import Control.Concurrent
import Control.Monad
import SdlInit
import SdlVideo

main :: IO ()
main = do
  ret <- sdlInit [VIDEO]
  when (not ret) $ fail "init failed."

  sur <- sdlSetVideoMode 640 480 32 [SWSURFACE,ANYFORMAT]
  img <- sdlLoadBMP "sample.bmp"

  let (width,height) = (surfaceWidth img, surfaceHeight img)
  let speed  = 5
      right  = 640-width
      bottom = 480-height
      move1  = zip [0,0+speed .. right] [0,0..]
      move2  = zip [right,right ..] [0,speed .. bottom]
      move3  = zip [right,right-speed .. 0] [bottom,bottom .. ]
      move4  = zip [0,0..] [bottom,bottom-speed .. 0]
      moveAll = move1 ++ move2 ++ move3 ++ move4

  mapM_ (\(x,y) -> do
    sdlFillRect sur Nothing 0x000000
    sdlBlitSurface img Nothing sur $ Just $ Rect x y width height
    sdlFlip sur
    threadDelay 16666
    ) moveAll

  sdlFreeSurface img
  sdlQuit

sample.bmpが画面をぐるりと回って終了。
まぁ、外界に対してはそれっぽいインターフェースが提供できた
ような感じではある。
とりあえず、全体のソースとWindowsバイナリをアップしておく。
wxHaskellから考えるとバイナリのサイズの小ささに感動。

http://fxp.infoseek.ne.jp/haskell/sdltest1.zip