diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,1 @@
+This is the license file.  Put stuff here.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,4 @@
+#! /usr/bin/env runhaskell
+
+> import Distribution.Simple
+> main = defaultMain
diff --git a/fallingblocks.cabal b/fallingblocks.cabal
new file mode 100644
--- /dev/null
+++ b/fallingblocks.cabal
@@ -0,0 +1,17 @@
+Name:                fallingblocks
+Version:             0.1
+Synopsis:            A fun falling blocks game.
+Description:         A game where blocks of different shapes fall down the screen.  If you
+		     either fill an entire line or get four of the same color in a row,
+		     those disappear.  How long can you go before the blocks fill the screen?
+License:             GPL
+License-file:        LICENSE
+Author:              Ben Sanders
+Copyright:	     (c) 2009 by Ben Sanders
+Maintainer:          Ben Sanders <bwsanders@gmail.com>
+Build-Depends:       base, SDL, haskell98, containers, SDL-ttf, SDL-mixer >= 0.5.5
+Build-Type:	     Simple
+Category:	     Game
+
+Executable:          fallingblocks
+Main-is:             main.hs
diff --git a/main.hs b/main.hs
new file mode 100644
--- /dev/null
+++ b/main.hs
@@ -0,0 +1,102 @@
+import Graphics.UI.SDL as SDL
+import Graphics.UI.SDL.TTF as TTF
+
+import Graphics.UI.SDL.Mixer as Mix
+
+import Game
+import Shape
+import Helpers
+import Board 
+
+import GameController
+import SplashController
+
+import GameState
+
+import Random (randomRIO)
+import Data.Maybe (isNothing)
+
+import GraphicsInfo
+
+main = do
+  SDL.init [InitEverything]
+  setVideoMode 400 400 32 []
+  TTF.init
+
+  setCaption "Falling Blocks!" "Falling Blocks!" 
+
+  mworked <- openAudio 44100 AudioS16Sys 2 4096
+  music <- loadMUS "music.mp3"
+  playMusic music (-1)
+
+  gi <- makeGraphics
+
+  enableKeyRepeat 500 30
+
+  c <- getRandomType
+  n <- getRandomType
+  gameLoop (GameState gi (newGame c n) 0 True music handleSplashEvents renderSplashScreen True)
+
+
+gameLoop :: GameState -> IO ()
+gameLoop gsfirst = do
+  gs <- addPiece gsfirst
+
+  --getEvents - would like to get all events from pollEvent
+  events <- getEvents pollEvent []
+
+  --handle input
+  let gs' = handleEvents events gs
+
+  --delay - probably want something a bit more
+  --        complex here to handle refresh rate
+  delay 10
+
+  doRender gs'
+
+  if (keepGoing gs')
+    then gameLoop $ tickAndMoveIfNeeded gs'
+    else cleanUp gs'
+
+cleanUp :: GameState -> IO ()
+cleanUp gs = do
+  cleanupGraphics $ grInfo gs
+  freeMusic $ mus gs
+  closeAudio
+  TTF.quit
+  SDL.quit
+
+
+
+getRandomType :: IO ShapeType 
+getRandomType = do
+  randomRIO (0,6) >>= \i ->
+      return (toEnum i::ShapeType)
+
+addPiece :: GameState -> IO GameState
+addPiece gsfirst =
+  if isNothing . nextBlock $ game gsfirst
+   then randomRIO (0,6) >>= \i -> 
+       return $ gsfirst {game = addBlock (game gsfirst) (toEnum i::ShapeType)}
+   else return gsfirst
+
+tickAndMoveIfNeeded :: GameState -> GameState
+tickAndMoveIfNeeded gs = if ticks gs > t && (stillRunning $ game gs) && (not $ paused gs)
+                         then gs { game = move (game gs) MoveDown,
+                                   ticks = 0 }
+                         else gs { ticks = (ticks gs) + 1 }
+    where t = 40 - floor (modifier)
+          modifier = 2.3 * (fromIntegral level) :: Float
+          level = curLevel $ game gs
+
+
+-- collects a list of all outstanding events from SDL
+getEvents :: IO Event -> [Event] -> IO [Event]
+getEvents pEvent es = do
+  e <- pEvent
+  let hasEvent = e /= NoEvent
+  if hasEvent
+   then getEvents pEvent (e:es)
+   else return (reverse es)
+
+
