diff --git a/Graphics/UI/SDL/MPEG.hs b/Graphics/UI/SDL/MPEG.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/UI/SDL/MPEG.hs
@@ -0,0 +1,72 @@
+module Graphics.UI.SDL.MPEG (
+    module Graphics.UI.SDL.MPEG,
+    module Graphics.UI.SDL.MPEG.Types,
+    module Graphics.UI.SDL.MPEG.General
+) where
+import Foreign
+import Foreign.C.String
+import Graphics.UI.SDL
+import Graphics.UI.SDL.MPEG.Types
+import Graphics.UI.SDL.MPEG.General
+
+-- | Create a new MPEG object from an MPEG file.
+load :: FilePath -> IO MPEG
+load fn = do
+    mpeg <- withCString fn $ \cstr -> _SMPEG_new cstr nullPtr 0
+    mkFinalizedMPEG mpeg
+
+-- | Create a new MPEG object from a file descriptor.
+loadFd :: Int -> IO MPEG
+loadFd fd = do
+    mpeg <- _SMPEG_new_descr fd nullPtr 0
+    mkFinalizedMPEG mpeg
+
+-- | Create a new MPEG object from a byte string.
+loadData :: CStringLen -> IO MPEG
+loadData (cstr, len) = do
+    mpeg <- _SMPEG_new_data (castPtr cstr) len nullPtr 0
+    mkFinalizedMPEG mpeg
+
+-- | Create a new MPEG object from a RWops structure.
+loadRWops :: RWops -> IO MPEG
+loadRWops rwops = withForeignPtr rwops $ \rptr -> do
+    mpeg <- _SMPEG_new_rwops rptr nullPtr 0
+    mkFinalizedMPEG mpeg
+
+-- | Set the SDL surface and the position the MPEG object is to be painted on.
+setSurface :: MPEG -> Surface -> Int -> Int -> IO ()
+setSurface mpeg surface x y = withForeignPtr mpeg $ \mptr -> do
+    withForeignPtr surface $ \sptr -> _SMPEG_setdisplay mptr sptr nullPtr nullFunPtr
+    _SMPEG_move mptr x y
+
+-- | Set the region of the video to be shown.
+setDisplayRegion :: MPEG -> Rect -> IO ()
+setDisplayRegion mpeg (Rect x y w h) = withForeignPtr mpeg $ \mptr -> do
+    _SMPEG_setdisplayregion mptr x y w h
+
+-- | Render a particular frame in the MPEG video
+renderFrame :: MPEG -> Int -> IO ()
+renderFrame mpeg i = withForeignPtr mpeg $ \mptr -> do
+    _SMPEG_renderFrame mptr i
+
+setScale :: MPEG -> Int -> IO ()
+setScale mpeg scale = withForeignPtr mpeg $ \mptr -> do
+    _SMPEG_scale mptr scale
+
+setScaleXY :: MPEG -> Int -> Int -> IO ()
+setScaleXY mpeg x y = withForeignPtr mpeg $ \mptr -> do
+    _SMPEG_scaleXY mptr x y
+
+enableAudio, enableVideo, enableLoop :: MPEG -> Bool -> IO ()
+enableAudio mpeg bool = withForeignPtr mpeg $ \mptr -> do
+    _SMPEG_enableaudio mptr (fromEnum bool)
+enableVideo mpeg bool = withForeignPtr mpeg $ \mptr -> do
+    _SMPEG_enablevideo mptr (fromEnum bool)
+enableLoop mpeg bool = withForeignPtr mpeg $ \mptr -> do
+    _SMPEG_loop mptr (fromEnum bool)
+
+play, pause, stop, rewind :: MPEG -> IO ()
+play   = (`withForeignPtr` _SMPEG_play)
+pause  = (`withForeignPtr` _SMPEG_pause)
+stop   = (`withForeignPtr` _SMPEG_stop)
+rewind = (`withForeignPtr` _SMPEG_rewind)
diff --git a/Graphics/UI/SDL/MPEG/General.hs b/Graphics/UI/SDL/MPEG/General.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/UI/SDL/MPEG/General.hs
@@ -0,0 +1,101 @@
+module Graphics.UI.SDL.MPEG.General where
+import Foreign
+import Foreign.C.String
+import Graphics.UI.SDL
+import Graphics.UI.SDL.MPEG.Types
+
+mkFinalizedMPEG :: Ptr MPEGStruct -> IO MPEG
+mkFinalizedMPEG = newForeignPtr _SMPEG_delete
+
+foreign import ccall unsafe "&SMPEG_delete" _SMPEG_delete
+    :: FunPtr (Ptr MPEGStruct -> IO ())
+
+foreign import ccall unsafe "SMPEG_new" _SMPEG_new
+    :: CString -> (Ptr InfoStruct) -> Int -> IO (Ptr MPEGStruct)
+
+foreign import ccall unsafe "SMPEG_new_descr" _SMPEG_new_descr
+    :: Int -> (Ptr InfoStruct) -> Int -> IO (Ptr MPEGStruct)
+
+foreign import ccall unsafe "SMPEG_new_data" _SMPEG_new_data
+    :: Ptr () -> Int -> (Ptr InfoStruct) -> Int -> IO (Ptr MPEGStruct)
+
+foreign import ccall unsafe "SMPEG_new_rwops" _SMPEG_new_rwops
+    :: Ptr RWopsStruct -> (Ptr InfoStruct) -> Int -> IO (Ptr MPEGStruct)
+
+foreign import ccall unsafe "SMPEG_renderFrame" _SMPEG_renderFrame
+    :: Ptr MPEGStruct -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_play" _SMPEG_play
+    :: Ptr MPEGStruct -> IO ()
+
+foreign import ccall unsafe "SMPEG_pause" _SMPEG_pause
+    :: Ptr MPEGStruct -> IO ()
+
+foreign import ccall unsafe "SMPEG_stop" _SMPEG_stop
+    :: Ptr MPEGStruct -> IO ()
+
+foreign import ccall unsafe "SMPEG_rewind" _SMPEG_rewind
+    :: Ptr MPEGStruct -> IO ()
+
+foreign import ccall unsafe "SMPEG_setdisplay" _SMPEG_setdisplay
+    :: Ptr MPEGStruct -> (Ptr SurfaceStruct) -> (Ptr MutexStruct) -> FunPtr DisplayCallback -> IO ()
+
+foreign import ccall unsafe "SMPEG_setdisplayregion" _SMPEG_setdisplayregion
+    :: Ptr MPEGStruct -> Int -> Int -> Int -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_move" _SMPEG_move
+    :: Ptr MPEGStruct -> Int -> Int -> IO ()
+
+foreign import ccall "wrapper"
+    mkDisplayCallback :: DisplayCallback -> IO (FunPtr DisplayCallback)
+
+foreign import ccall unsafe "SMPEG_getinfo" _SMPEG_getinfo
+    :: Ptr MPEGStruct -> Ptr InfoStruct -> IO ()
+
+foreign import ccall unsafe "SMPEG_enableaudio" _SMPEG_enableaudio
+    :: Ptr MPEGStruct -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_enablevideo" _SMPEG_enablevideo
+    :: Ptr MPEGStruct -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_status" _SMPEG_status
+    :: Ptr MPEGStruct -> IO Int
+
+foreign import ccall unsafe "SMPEG_setvolume" _SMPEG_setvolume
+    :: Ptr MPEGStruct -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_loop" _SMPEG_loop
+    :: Ptr MPEGStruct -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_scaleXY" _SMPEG_scaleXY
+    :: Ptr MPEGStruct -> Int -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_scale" _SMPEG_scale
+    :: Ptr MPEGStruct -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_seek" _SMPEG_seek
+    :: Ptr MPEGStruct -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_skip" _SMPEG_skip
+    :: Ptr MPEGStruct -> Float -> IO ()
+
+foreign import ccall unsafe "SMPEG_renderFinal" _SMPEG_renderFinal
+    :: Ptr MPEGStruct -> Ptr SurfaceStruct -> Int -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_filter" _SMPEG_filter
+    :: Ptr MPEGStruct -> Ptr FilterStruct -> IO (Ptr FilterStruct)
+
+foreign import ccall unsafe "SMPEG_error" _SMPEG_error
+    :: Ptr MPEGStruct -> IO CString
+
+foreign import ccall unsafe "SMPEG_playAudio" _SMPEG_playAudio
+    :: Ptr MPEGStruct -> CString -> Int -> IO Int
+
+foreign import ccall unsafe "SMPEG_playAudioSDL" _SMPEG_playAudioSDL
+    :: Ptr MPEGStruct -> CString -> Int -> IO ()
+
+foreign import ccall unsafe "SMPEG_wantedSpec" _SMPEG_wantedSpec
+    :: Ptr MPEGStruct -> Ptr AudioSpecStruct -> IO Int
+
+foreign import ccall unsafe "SMPEG_actualSpec" _SMPEG_actualSpec
+    :: Ptr MPEGStruct -> Ptr AudioSpecStruct -> IO ()
diff --git a/Graphics/UI/SDL/MPEG/Types.hs b/Graphics/UI/SDL/MPEG/Types.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/UI/SDL/MPEG/Types.hs
@@ -0,0 +1,32 @@
+module Graphics.UI.SDL.MPEG.Types where
+import Foreign
+import Graphics.UI.SDL
+
+newtype MutexStruct = MkMutexStruct ()
+type Mutex = ForeignPtr MutexStruct
+
+newtype MPEGStruct = MkMPEGStruct ()
+type MPEG = ForeignPtr MPEGStruct
+
+newtype InfoStruct = MkInfoStruct ()
+type Info = ForeignPtr InfoStruct
+
+newtype FilterStruct = MkFilterStruct ()
+type Filter = ForeignPtr FilterStruct
+
+newtype AudioSpecStruct = MkAudioSpecStruct ()
+type AudioSpec = ForeignPtr AudioSpecStruct
+
+type DisplayCallback = Ptr SurfaceStruct -> Int -> Int -> Int -> Int -> IO ()
+
+data Status = SMPEG_ERROR | SMPEG_STOPPED | SMPEG_PLAYING
+    deriving (Eq, Ord, Bounded)
+
+instance Enum Status where
+    toEnum (-1) = SMPEG_ERROR
+    toEnum 0    = SMPEG_STOPPED
+    toEnum 1    = SMPEG_PLAYING
+    toEnum _    = error "Status's enum value should be -1, 0 or 1"
+    fromEnum SMPEG_ERROR   = -1
+    fromEnum SMPEG_STOPPED = 0
+    fromEnum SMPEG_PLAYING = 1
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,18 @@
+Copyright 2008 by Audrey Tang
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+  
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+   
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README b/README
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,11 @@
+This package contains Haskell bindings to the SMPEG library >= 0.4.4
+
+Global installation:
+  runhaskell Setup.lhs configure
+  runhaskell Setup.lhs build
+  runhaskell Setup.lhs install # as root
+
+Local installation:
+  runhaskell Setup.lhs configure --prefix=[HOME]/usr --user
+  runhaskell Setup.lhs build
+  runhaskell Setup.lhs install --user # not as root
diff --git a/SDL-mpeg.cabal b/SDL-mpeg.cabal
new file mode 100644
--- /dev/null
+++ b/SDL-mpeg.cabal
@@ -0,0 +1,18 @@
+Name            : SDL-mpeg
+Version         : 0.0.1
+Maintainer      : Audrey Tang
+Author          : Audrey Tang
+Copyright       : 2008, Audrey Tang
+License-File    : LICENSE
+License         : BSD3
+Build-Depends   : base, SDL
+Build-Type      : Simple
+Category        : Foreign binding
+Synopsis        : Binding to the SMPEG library
+Description     : Binding to the SMPEG library
+Extensions      : ForeignFunctionInterface
+Exposed-Modules : Graphics.UI.SDL.MPEG Graphics.UI.SDL.MPEG.Types Graphics.UI.SDL.MPEG.General
+Includes        : smpeg.h
+Data-Files      : README
+GHC-Options     : -Wall
+Extra-Libraries : smpeg
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,5 @@
+#!/usr/bin/env runhaskell
+> module Main where
+> import Distribution.Simple
+> main :: IO ()
+> main = defaultMain
