diff --git a/FunGEn.cabal b/FunGEn.cabal
--- a/FunGEn.cabal
+++ b/FunGEn.cabal
@@ -1,18 +1,18 @@
 name:               FunGEn
-version:            0.3
-copyright:          (C) 2002 Andre Furtado <awbf@cin.ufpe.br>, (C) 2008 Miloslav Raus <666wman@gmail.com>, (C) 2008,2011 Simon Michael <simon@joyful.com>
+version:            0.4
+copyright:          (C) 2002 Andre Furtado <awbf@cin.ufpe.br>
 license:            BSD3
 license-file:       LICENSE
 author:             Andre Furtado <awbf@cin.ufpe.br>
 maintainer:         Simon Michael <simon@joyful.com>
-homepage:           http://darcsden.com/simon/fungen
+homepage:           http://joyful.com/fungen
 category:           Game
 synopsis:           FUNctional Game ENgine
 description:        Multi-platform 2D game engine built on top of OpenGL & GLUT
-stability:          experimental
+stability:          alpha
 cabal-version:      >= 1.6
 build-type:         Simple
-tested-with:        GHC==6.12
+tested-with:        GHC==7.6.3
 extra-source-files: README.md, examples/pong/hit.wav, examples/pong/pong.hs, examples/pong/tex.bmp,
                     examples/worms/border1.bmp, examples/worms/border2.bmp, examples/worms/border3.bmp,
                     examples/worms/congratulations.bmp, examples/worms/food.bmp, examples/worms/free1.bmp,
@@ -22,15 +22,14 @@
                     examples/worms/level3.bmp, examples/worms/segment.bmp, examples/worms/worms.hs
 
 library
-  exposed-modules: Graphics.UI.Fungen,
-                   Graphics.UI.Fungen.Types, Graphics.UI.Fungen.Util, Graphics.UI.Fungen.Loader,
-                   Graphics.UI.Fungen.Objects, Graphics.UI.Fungen.Map, Graphics.UI.Fungen.Game,
-                   Graphics.UI.Fungen.Display, Graphics.UI.Fungen.Input, Graphics.UI.Fungen.Timer,
-                   Graphics.UI.Fungen.Text, Graphics.UI.Fungen.Init, Graphics.UI.Fungen.UserInput
+  exposed-modules:  Graphics.UI.Fungen,
+                    Graphics.UI.Fungen.Types, Graphics.UI.Fungen.Util, Graphics.UI.Fungen.Loader,
+                    Graphics.UI.Fungen.Objects, Graphics.UI.Fungen.Map, Graphics.UI.Fungen.Game,
+                    Graphics.UI.Fungen.Display, Graphics.UI.Fungen.Input, Graphics.UI.Fungen.Timer,
+                    Graphics.UI.Fungen.Text, Graphics.UI.Fungen.Init, Graphics.UI.GLUT.Input
 
   build-depends:
-                 base == 4.*
-                 ,OpenGL
-                 ,GLUT
-                 ,haskell98
-                 ,random
+                    base == 4.*
+                   ,OpenGL
+                   ,GLUT
+                   ,random
diff --git a/Graphics/UI/Fungen/Game.hs b/Graphics/UI/Fungen/Game.hs
--- a/Graphics/UI/Fungen/Game.hs
+++ b/Graphics/UI/Fungen/Game.hs
@@ -68,7 +68,39 @@
 -- 
 -- * v is the type of the map tile special attribute, in case we use a Tile Map as the background of our game
 -- 
--- A game consists of:
+-- For a mnemonic, uh...
+--
+-- * t - /T/op-level game attribute type,
+--
+-- * s - /S/prite object attribute type,
+--
+-- * u - /U/pdating game state type,
+--
+-- * v - /V/icinity (map tile) attribute type.
+-- 
+-- A Game consists of the following attributes, accessible via the
+-- accessor functions below:
+--
+-- * @gameMap       :: IORef (GameMap v)         -- a map (background)@
+--
+-- * @gameState     :: IORef u                   -- initial game state@
+--
+-- * @gameFlags     :: IORef GameFlags           -- initial game flags@
+--
+-- * @objManagers   :: IORef [(ObjectManager s)] -- some object managers@
+--
+-- * @textList      :: IORef [Text]              -- some texts@
+--
+-- * @quadricObj    :: QuadricPrimitive          -- a quadric thing@
+--
+-- * @windowConfig  :: IORef WindowConfig        -- a config for the main window@
+--
+-- * @gameAttribute :: IORef t                   -- a game attribute@
+--
+-- * @pictureList   :: IORef [TextureObject]     -- some pictures@
+--
+-- * @fpsInfo       :: IORef (Int,Int,Float)     -- only for debugging@
+-- 
 data Game t s u v = Game {
 	gameMap       :: IORef (GameMap v), -- ^ a map (background)
     	gameState     :: IORef u,           -- ^ initial game state
@@ -82,7 +114,7 @@
 	fpsInfo       :: IORef (Int,Int,Float)  -- only for debugging
 	}
 
--- | A game action has the type @IOGame t s u v a@, where t, s, u and v
+-- | A game action (IOGame) has the type @IOGame t s u v a@, where t, s, u and v
 -- are as for Game and a is the type returned by each action of the game
 -- (such as the Int for "IO Int").  The name IOGame was chosen to remind
 -- that each action deals with a Game, but an IO operation can also be
diff --git a/Graphics/UI/Fungen/Init.hs b/Graphics/UI/Fungen/Init.hs
--- a/Graphics/UI/Fungen/Init.hs
+++ b/Graphics/UI/Fungen/Init.hs
@@ -28,7 +28,7 @@
 import Graphics.Rendering.OpenGL
 import Graphics.UI.GLUT
 
-funInit :: WindowConfig -> GameMap v -> [(ObjectManager s)] -> u -> t -> [InputConfig t s u v] -> IOGame t s u v () -> RefreshType -> FilePictureList -> IO ()
+funInit :: WindowConfig -> GameMap v -> [(ObjectManager s)] -> u -> t -> [InputBinding t s u v] -> IOGame t s u v () -> RefreshType -> FilePictureList -> IO ()
 funInit winConfig@((px,py),(sx,sy),t) userMap objectGroups gState gAttrib i gameCicle r picList = do
         initialize "FunGen app" []
         createWindow t -- (return ()) [ Double, RGBA ]
diff --git a/Graphics/UI/Fungen/Input.hs b/Graphics/UI/Fungen/Input.hs
--- a/Graphics/UI/Fungen/Input.hs
+++ b/Graphics/UI/Fungen/Input.hs
@@ -14,22 +14,29 @@
 -}
 
 module Graphics.UI.Fungen.Input (
-        InputConfig,
-        Key(..), KeyEvent(..), SpecialKey(..), MouseButton(..),
+        InputBinding, InputHandler,
+        Key(..), KeyEvent(..), SpecialKey(..), MouseButton(..), Modifiers(..), Position(..),
         funBinding
 ) where
 
 import Graphics.UI.Fungen.Game
-import Graphics.UI.Fungen.UserInput
 import Graphics.UI.GLUT
+import Graphics.UI.GLUT.Input (KeyEvent(..), KeyBinder, StillDownHandler, initGLUTInput)
 
-type InputConfig t s u v = (Key,KeyEvent,IOGame t s u v ())
+-- | A FunGEn input handler (which we use instead of GLUTInput's) is
+-- an IOGame (game action) that takes two extra arguments: the current
+-- keyboard modifiers state, and the current mouse position. (For a StillDown
+-- event, these will be the original state and position from the Press event.)
+type InputHandler t s u v = Modifiers -> Position -> IOGame t s u v ()
 
-funBinding :: [InputConfig t s u v] -> Game t s u v -> IO (KeyBinder, StillDownHandler)
+-- | A mapping from an input event to an input handler.
+type InputBinding t s u v = (Key, KeyEvent, InputHandler t s u v)
+
+funBinding :: [InputBinding t s u v] -> Game t s u v -> IO (KeyBinder, StillDownHandler)
 funBinding inputs g = do
-        (bindKey, stillDown) <- initUserInput
+        (bindKey, stillDown) <- initGLUTInput
         mapM (userBinding g bindKey) inputs 
         return (bindKey, stillDown)
 
-userBinding :: Game t s u v -> KeyBinder -> InputConfig t s u v -> IO ()
-userBinding g bindKey (key,keyEvent,gameAction) = bindKey key keyEvent (Just (runIOGameM gameAction g))
+userBinding :: Game t s u v -> KeyBinder -> InputBinding t s u v -> IO ()
+userBinding g bindKey (key, keyEvent, inputHandler) = bindKey key keyEvent (Just (\mods pos -> runIOGameM (inputHandler mods pos) g))
diff --git a/Graphics/UI/Fungen/Timer.hs b/Graphics/UI/Fungen/Timer.hs
--- a/Graphics/UI/Fungen/Timer.hs
+++ b/Graphics/UI/Fungen/Timer.hs
@@ -18,8 +18,8 @@
         setRefresh
 ) where
 
-import Graphics.UI.Fungen.UserInput
 import Graphics.UI.GLUT
+import Graphics.UI.GLUT.Input
 
 data RefreshType
         = Idle
diff --git a/Graphics/UI/Fungen/UserInput.hs b/Graphics/UI/Fungen/UserInput.hs
deleted file mode 100644
--- a/Graphics/UI/Fungen/UserInput.hs
+++ /dev/null
@@ -1,82 +0,0 @@
-{- |
-   GLUT-based keyboard/mouse handling
-   Sven Panne 2000.   mailto:Sven.Panne@informatik.uni-muenchen.de
--}
-
-module Graphics.UI.Fungen.UserInput (
-   Key(..), KeyEvent(..), KeyBinder, StillDownHandler, initUserInput
-) where
-
-import Data.IORef(IORef, newIORef, readIORef, modifyIORef)
-import Data.List(delete)
-import Graphics.UI.GLUT
-
----------------------------------------------------------------------------
-
-data KeyEvent = Press | StillDown | Release   deriving Eq
-
----------------------------------------------------------------------------
-
-type KeyTable = IORef [Key]
-
-newKeyTable :: IO KeyTable
-newKeyTable = newIORef []
-
-getKeys :: KeyTable -> IO [Key]
-getKeys = readIORef
-
-insertIntoKeyTable :: KeyTable -> Key -> IO ()
-insertIntoKeyTable keyTab key = modifyIORef keyTab (key:)
-
-deleteFromKeyTable :: KeyTable -> Key -> IO ()
-deleteFromKeyTable keyTab key = modifyIORef keyTab (delete key)
-
----------------------------------------------------------------------------
-
-type KeyBinder = Key -> KeyEvent -> Maybe (IO ()) -> IO ()
-
--- TODO: Improve type
-type BindingTable = IORef [((Key,KeyEvent), IO ())]
-
-newBindingTable :: IO BindingTable
-newBindingTable = newIORef []
-
-bindKey :: BindingTable -> KeyBinder
-bindKey bindingTable key event Nothing =
-   modifyIORef bindingTable (\t -> [ e | e@(b,a) <- t, b /= (key, event)])
-bindKey bindingTable key event (Just action) = do
-   bindKey bindingTable key event Nothing
-   modifyIORef bindingTable (((key, event), action) :)
-
-execAction :: BindingTable -> Key -> KeyEvent -> IO ()
-execAction bindingTable key event =
-   readIORef bindingTable >>= (maybe (return ()) id . lookup (key, event))
-
----------------------------------------------------------------------------
-
-type StillDownHandler = IO ()
-
-stillDown :: BindingTable -> KeyTable -> StillDownHandler
-stillDown bindingTable pressedKeys =
-   getKeys pressedKeys >>= mapM_ (\k -> execAction bindingTable k StillDown)
-
----------------------------------------------------------------------------
-
-initUserInput :: IO (KeyBinder, StillDownHandler)
-initUserInput = do
-   -- Using "setKeyRepeat KeyRepeatOff" would be a little bit more
-   -- efficient, but has two disadvantages: It is not yet implemented
-   -- for M$ and it changes the global state of X11.
-   globalKeyRepeat $= GlobalKeyRepeatOff
-   bindingTable <- newBindingTable
-   pressedKeys  <- newKeyTable
-   let keyPress   k = do insertIntoKeyTable pressedKeys k
-                         execAction bindingTable k Press
-       keyRelease k = do deleteFromKeyTable pressedKeys k
-                         execAction bindingTable k Release
-       keyboardMouse k Down _ _ = keyPress   k
-       keyboardMouse k Up   _ _ = keyRelease k
-   keyboardMouseCallback $= Just keyboardMouse
-   return (bindKey bindingTable, stillDown bindingTable pressedKeys)
-
-
diff --git a/Graphics/UI/GLUT/Input.hs b/Graphics/UI/GLUT/Input.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/UI/GLUT/Input.hs
@@ -0,0 +1,102 @@
+{- |
+GLUT-based keyboard/mouse handling.
+
+Sven Panne 2000 <Sven.Panne@informatik.uni-muenchen.de>
+
+This provides a "still down" event in addition to GLUT's key/mouse
+button up/down events, and manages bindings from input events to actions.
+
+-}
+
+module Graphics.UI.GLUT.Input (
+   Key(..), KeyEvent(..), KeyBinder, InputHandler, StillDownHandler, initGLUTInput
+) where
+
+import Data.IORef(IORef, newIORef, readIORef, modifyIORef)
+import Data.List(deleteBy)
+import Graphics.UI.GLUT
+
+---------------------------------------------------------------------------
+
+data KeyEvent = Press | StillDown | Release   deriving Eq
+
+---------------------------------------------------------------------------
+
+-- | A mutable list of keys (or mouse buttons), along with modifier
+-- state and mouse position.
+type KeyTable = IORef [(Key, Modifiers, Position)]
+
+newKeyTable :: IO KeyTable
+newKeyTable = newIORef []
+
+getKeys :: KeyTable -> IO [(Key, Modifiers, Position)]
+getKeys = readIORef
+
+insertIntoKeyTable :: KeyTable -> Key -> Modifiers -> Position -> IO ()
+insertIntoKeyTable keyTab key mods pos = modifyIORef keyTab ((key,mods,pos):)
+
+deleteFromKeyTable :: KeyTable -> Key -> IO ()
+deleteFromKeyTable keyTab key = modifyIORef keyTab (deleteBy (\(k,_,_) (l,_,_) -> k==l) (key, nullmods, nullpos))
+  where nullmods = Modifiers Up Up Up
+        nullpos = Position 0 0
+
+---------------------------------------------------------------------------
+
+type InputHandler = Modifiers -> Position -> IO ()
+
+type KeyBinder = Key -> KeyEvent -> Maybe InputHandler -> IO ()
+
+-- TODO: Improve type 
+
+-- | A mutable list of mappings from key/mousebutton up/down/stilldown
+-- events to IO actions.
+type BindingTable = IORef [((Key,KeyEvent), InputHandler)]
+
+newBindingTable :: IO BindingTable
+newBindingTable = newIORef []
+
+bindKey :: BindingTable -> KeyBinder
+bindKey bindingTable key event Nothing =
+   modifyIORef bindingTable (\t -> [ e | e@(b,a) <- t, b /= (key, event)])
+bindKey bindingTable key event (Just action) = do
+   bindKey bindingTable key event Nothing
+   modifyIORef bindingTable (((key, event), action) :)
+
+execAction :: BindingTable -> Key -> KeyEvent -> Modifiers -> Position -> IO ()
+execAction bindingTable key event mods pos  =
+   readIORef bindingTable >>= (maybe (return ()) (\a -> a mods pos) . lookup (key, event))
+
+---------------------------------------------------------------------------
+
+type StillDownHandler = IO ()
+
+stillDown :: BindingTable -> KeyTable -> StillDownHandler
+stillDown bindingTable pressedKeys =
+   getKeys pressedKeys >>= mapM_ (\(k,mods,pos) -> execAction bindingTable k StillDown mods pos)
+
+---------------------------------------------------------------------------
+
+-- | Initialise the input system, which keeps a list of input event to
+-- action bindings and executes the the proper actions automatically.
+-- Returns a function for adding bindings, and another which should be
+-- called periodically (eg from refresh) to trigger still-down actions.
+initGLUTInput :: IO (KeyBinder, StillDownHandler)
+initGLUTInput = do
+   -- Using "setKeyRepeat KeyRepeatOff" would be a little bit more
+   -- efficient, but has two disadvantages: It is not yet implemented
+   -- for M$ and it changes the global state of X11.
+   globalKeyRepeat $= GlobalKeyRepeatOff
+   bindingTable <- newBindingTable
+   pressedKeys  <- newKeyTable
+   let keyPress k mods pos = do
+         insertIntoKeyTable pressedKeys k mods pos
+         execAction bindingTable k Press mods pos
+       keyRelease k mods pos = do 
+         deleteFromKeyTable pressedKeys k
+         execAction bindingTable k Release mods pos
+       keyboardMouse k Down mods pos = keyPress   k mods pos
+       keyboardMouse k Up   mods pos = keyRelease k mods pos
+   keyboardMouseCallback $= Just keyboardMouse
+   return (bindKey bindingTable, stillDown bindingTable pressedKeys)
+
+
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 Copyright (C) 2002 Andre Furtado <awbf@cin.ufpe.br>
 Copyright (C) 2008 Miloslav Raus <666wman@gmail.com>
-Copyright (C) 2008,2011 Simon Michael <simon@joyful.com>
+Copyright (C) 2008,2011-2013 Simon Michael <simon@joyful.com>
 
 All rights reserved.
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,143 +1,175 @@
-# FunGEN - Functional Game Engine
-
-FunGEn (Functional Game Engine) is a BSD-licensed 2D platform-independent
-game engine implemented in and for Haskell, using HOpenGL. It is intended
-to help game programmers in the game development process, in a faster and
-automated way. Actually, FunGEn supports:
-
-- Initialization, updating, removing, rendering and grouping routines for game objects;
-- Definition of a game background (or map), including texture-based maps and tile maps;
-- Reading and intepretation of the player's keyboard input;
-- Collision detection;
-- Time-based functions and pre-defined game actions;
-- Loading and displaying of 24-bit bitmap files;
-- Debugging and game performance evaluation facilities;
-- Sound support (actually for windows platforms only... :-[ );
-- Hope to expand this list soon :-]
-
-This README includes most of the docs from the original site, lightly updated.
-There is also a [tutorial](TUTORIAL.html).
-
-Original home:  [http://www.cin.ufpe.br/\~haskell/fungen](http://www.cin.ufpe.br/\~haskell/fungen)
-
-Latest code:    [http://darcsden.com/simon/fungen](http://darcsden.com/simon/fungen)
-
-Latest haddock: [http://joyful.com/repos/fungen/dist/doc/html/FunGEn/](http://joyful.com/repos/fungen/dist/doc/html/fungen/)
-
-Hackage:        [http://hackage.haskell.org/package/FunGEn](http://hackage.haskell.org/package/FunGEn)
-
-Copyright:      [LICENSE](./LICENSE)
-
-## History
-
-* Cabalised ghc 6.12-compatible 0.3 released on darcsden & hackage by Simon Michael (2011/02)
-
-* Cabalised ghc 6.10-compatible 0.1 released on hackage by Miloslav Raus (2008/09)
-
-    *Tested under Win32 & Linux/Intel. Known glitches: Flickering under
-    linux (at least on my shitty laptop). Weird pong paddle behavior under
-    Win32.*
-
-* Repo-ised ghc 6.8-compatible update by Simon Michael (2008/02)
-
-* 0.1 released by Andre Furtado (2002)
-
-    *Current Status:Some feedback indicated that the first version of
-    FunGEn was not as "functional" as it was desired: some game issues
-    were still being dealt through an imperative fashion. This way, the
-    authors of this project decided to change the game engine philosophy:
-    programmers should describe a game as a set of "specifications" rather
-    than defining its behavior imperatively. One plausible alternative for
-    accomplishing this task is porting the Clean Game Library (CGL) to
-    Haskell, adding some FunGEn specific features. Hence, this is the
-    actual status of the FunGEn project: it is being rebuilt in order to
-    provide game programming mechanisms following the CGL concepts. This
-    really demands some time, but the authors expect a new version to be
-    released soon.*
-
-    *FunGEn v1.0 can be downloaded here. (PLEASE NOTE: this is the very
-    first version of FunGEn, and it was released just to get some feedback
-    from game programmers. You are strongly invited to tell your game
-    programming experiences with FunGEn, helping us to release a
-    definitive, stable version). Ok, after this disclaimer, please fell
-    yourself free to take a quick tour in the site; it contains a lot of
-    useful information for those who are really interested in trying a new
-    game programming experience. Nice coding...*
-
-## Credits
-
-FunGEn was created by a Computation Science graduation student, at the
-Informatics Center (CIn) of the Federal University of Pernambuco (UFPE),
-as part of a Scientific Iniciation (PIBIC/CNPq) research project (Creating
-a Game Platform Using Haskell), oriented by lecturer Andre Santos (PhD,
-1995, University of Glasgow). He was responsible for figuring out a lot of
-FunGEn implementation details.
-
-I would like to thank also the following people who contributed for the development of FunGEn:
-
-- Sven Panne
-- Jay Cox
-- Geber Ramalho
-- Carlos Andre Pessoa
-- Charles Madeira
-- Monique Monteiro
-- The people at the Haskell mailing lists
-
-FunGEn can be distributed freely, in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-or FITNESS FOR A PARTICULAR PURPOSE. I would thank you if you cite my name
-and this site if you are going to use FunGEn for other things besides home
-programming.
-
-## To do
-
-Andre's 2002 list:
-
-Here you have a list of some upcoming FunGEn features, and some other
-desired features (but with no implementation prevision yet).
-
-- Support map scrolling (coming soon);
-- Support mouse input management (coming soon);
-- Make a polygon map definition avaiable (coming soon);
-- Make sound avaible to non-Win32 platforms;
-- Create, if possible, some operators to avoid the excessive (x <- ...) syntax;
-- Support auto-animated objects;
-- Create a GLUT independent font support (or perhaps extend it);
-- Improve the installation process;
-- Upgrade FunGEn to be both a 2D (bidimensional) and 2D 1/2 (bi and a half dimensional) engine;
-- Create a map editor/generator (possibly in other language, or using the brand new Haskell GUI...);
-- Take courage to start thinking about the 3D world...
-
-Would you like to suggest a feature? Feel free to do it. Would you like to
-implement a feature? Please do it! Keep in touch.
-
-## FAQ
-
-**What is a game engine?**
-
-A game engine can be considered as a library that provides game facilities
-to a game programmer. When using a game engine, the programmer must
-specify when the game events happen, rather than how they are
-implemented. A same functionality may have its implementation varying from
-platform to platform, in the case the engine is platform-independent. The
-main advantage of a game engine is that it can be reused to the
-development of many different kind of games, in an automated way, saving a
-lot of programming time.
-
-**Why Haskell?**
-
-We believe that Haskell is a great language to develop games, because of
-its high level of abstraction and the generation of a more concise,
-elegant and shorter code. This is great for code maintenance and
-understanding. Combining the power of Haskell with the facilities provided
-by game engines seems a promising project. You can find more info on
-Haskell in its official site.
-
-**What is HOpenGL?**
-
-HOpenGL stands for Haskell Open Graphics Library. Actually, it is a
-binding to one of the most famous graphics libraries around the world
-(OpenGL) and its auxiliary toolkit (GLUT). In other words, it makes
-possible to call OpenGL/GLUT routines (which were written in the C
-language) when programming in Haskell. You can find more info on HOpenGL
-in my HOpenGL Tutorial site, or in its official site.
+<style>
+.a {
+    font-weight:bold;
+    color:red;
+    font-size:200%;
+}
+.b {
+    font-weight:normal;
+    color:#bbb;
+    font-size:smaller;
+}
+</style>
+
+# <span class="a">Fun<span class="b">ctional</span> G<span class="b">ame</span> En<span class="b">gine</span></span>
+
+FunGEn (Functional Game Engine) is a cross-platform, BSD-licensed,
+OpenGL-based 2D game engine written in Haskell. It is intended to help
+game programmers make games in a faster and more automated way. FunGEn
+supports:
+
+- Initialization, updating, removing, rendering and grouping routines for game objects;
+- Definition of a game background (or map), including texture-based maps and tile maps;
+- Reading and intepretation of the player's keyboard input;
+- Collision detection;
+- Time-based functions and pre-defined game actions;
+- Loading and displaying of 24-bit bitmap files;
+- Debugging and game performance evaluation facilities;
+- Sound support (actually for windows platforms only... :-[ );
+- Hope to expand this list soon :-]
+
+Home:               [http://joyful.com/fungen](http://joyful.com/fungen)  
+Docs:               [Original docs](old-site/index.html), moved here from the [old site](http://www.cin.ufpe.br/~haskell/fungen). <!-- Another version of the [pong tutorial](TUTORIAL.html). --> A [video of the worms demo](http://www.youtube.com/watch?v=XRG9H0oC2Fw).  
+Hackage & API docs: [http://hackage.haskell.org/package/FunGEn](http://hackage.haskell.org/package/FunGEn)  
+Latest code:        [http://hub.darcs.net/simon/fungen](http://hub.darcs.net/simon/fungen)  
+Discussion & help:  [#haskell-game](irc://irc.freenode.net/#haskell-game) or [haskell-cafe](http://www.haskell.org/haskellwiki/Mailing_lists)  
+
+## Getting started
+
+    cabal install FunGEn
+
+## FAQ
+
+**What is a game engine?**
+
+A game engine can be considered as a library that provides game facilities
+to a game programmer. When using a game engine, the programmer must
+specify when the game events happen, rather than how they are
+implemented. A same functionality may have its implementation varying from
+platform to platform, in the case the engine is platform-independent. The
+main advantage of a game engine is that it can be reused to the
+development of many different kind of games, in an automated way, saving a
+lot of programming time.
+
+**Why Haskell?**
+
+We believe that Haskell is a great language to develop games, because of
+its high level of abstraction and the generation of a more concise,
+elegant and shorter code. This is great for code maintenance and
+understanding. Combining the power of Haskell with the facilities provided
+by game engines seems a promising project. You can find more info on
+Haskell in its official site.
+
+**What is HOpenGL?**
+
+HOpenGL stands for Haskell Open Graphics Library. Actually, it is a
+binding to one of the most famous graphics libraries around the world
+(OpenGL) and its auxiliary toolkit (GLUT). In other words, it makes
+possible to call OpenGL/GLUT routines (which were written in the C
+language) when programming in Haskell. You can find more info on HOpenGL
+in my HOpenGL Tutorial site, or in its official site.
+
+## Release notes
+
+### 0.4 (2013/08/05)
+
+* a new hakyll-based website, incorporating the old site
+* input handlers now receive mouse position and modifier state
+  (inspired by Pradeep Kumar).  See fungentest.hs for examples.
+* more haddocks
+
+### 0.3 (2011/02/13)
+GHC 6.12-compatible 0.3 [released](http://thread.gmane.org/gmane.comp.lang.haskell.cafe/86330) on darcsden & hackage by Simon Michael:
+
+- updated for GHC 6.12 & base 4
+- module names simplified
+- beginning of haddockification
+- docs moved into repo
+- published to darcsden, hackage, wiki, haskell-cafe, #haskell-game, reddit
+
+### 0.1-hackage (2008/09/17)
+GHC 6.10-compatible 0.1 released on hackage by Miloslav Raus:
+
+- updated for GHC 6.10
+- cabalised
+- Tested under Win32 & Linux/Intel. Known glitches: Flickering under linux
+  (at least on my shitty laptop). Weird pong paddle behavior under Win32.
+
+### GHC 6.8 update (2008/02/26)
+GHC 6.8-compatible update by Simon Michael:
+
+- updated for GHC 6.8
+- slight tweaks to examples
+- public darcs repo
+
+### 0.1 (2002)
+First public release by Andre Furtado:
+
+- FunGEn v1.0 can be downloaded here. (PLEASE NOTE: this is the very first
+  version of FunGEn, and it was released just to get some feedback from
+  game programmers. You are strongly invited to tell your game programming
+  experiences with FunGEn, helping us to release a definitive, stable
+  version). Ok, after this disclaimer, please fell yourself free to take a
+  quick tour in the site; it contains a lot of useful information for
+  those who are really interested in trying a new game programming
+  experience. Nice coding...
+
+- Current Status: Some feedback indicated that the first version of FunGEn
+  was not as "functional" as it was desired: some game issues were still
+  being dealt through an imperative fashion. This way, the authors of this
+  project decided to change the game engine philosophy: programmers should
+  describe a game as a set of "specifications" rather than defining its
+  behavior imperatively. One plausible alternative for accomplishing this
+  task is porting the Clean Game Library (CGL) to Haskell, adding some
+  FunGEn specific features. Hence, this is the actual status of the FunGEn
+  project: it is being rebuilt in order to provide game programming
+  mechanisms following the CGL concepts. This really demands some time,
+  but the authors expect a new version to be released soon.
+
+## Contributing
+
+Andre's 2002 todo list:
+
+Here you have a list of some upcoming FunGEn features, and some other
+desired features (but with no implementation prevision yet).
+
+- Support map scrolling (coming soon);
+- Support mouse input management (coming soon);
+- Make a polygon map definition avaiable (coming soon);
+- Make sound avaible to non-Win32 platforms;
+- Create, if possible, some operators to avoid the excessive (x <- ...) syntax;
+- Support auto-animated objects;
+- Create a GLUT independent font support (or perhaps extend it);
+- Improve the installation process;
+- Upgrade FunGEn to be both a 2D (bidimensional) and 2D 1/2 (bi and a half dimensional) engine;
+- Create a map editor/generator (possibly in other language, or using the brand new Haskell GUI...);
+- Take courage to start thinking about the 3D world...
+
+Would you like to suggest a feature? Feel free to do it. Would you like to
+implement a feature? Please do it! Keep in touch.
+
+## Credits
+
+FunGEn was created by Andre Furtado, Computation Science graduation
+student at the Informatics Center (CIn) of the Federal University of
+Pernambuco (UFPE), as part of a Scientific Iniciation (PIBIC/CNPq)
+research project (Creating a Game Platform Using Haskell), oriented by
+lecturer Andre Santos (PhD, 1995, University of Glasgow), who was
+responsible for figuring out a lot of FunGEn implementation details.
+
+I would like to thank also the following people who contributed for the development of FunGEn:
+
+- Sven Panne
+- Jay Cox
+- Geber Ramalho
+- Carlos Andre Pessoa
+- Charles Madeira
+- Monique Monteiro
+- The people at the Haskell mailing lists
+
+FunGEn can be distributed freely, in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. I would thank you if you cite my name
+and this site if you are going to use FunGEn for other things besides home
+programming.
+
diff --git a/examples/pong/pong.hs b/examples/pong/pong.hs
--- a/examples/pong/pong.hs
+++ b/examples/pong/pong.hs
@@ -17,9 +17,6 @@
 
 data GameAttribute = Score Int
  
-type PongObject = GameObject ()
-type PongAction a = IOGame GameAttribute () () () a
-
 width = 400
 height = 400
 w = fromIntegral width :: GLdouble
@@ -33,23 +30,23 @@
             bar    = objectGroup "barGroup"  [createBar]
             ball   = objectGroup "ballGroup" [createBall]
             initScore = Score 0
-            input = [(SpecialKey KeyRight, StillDown, moveBarToRight),
-                     (SpecialKey KeyLeft,  StillDown, moveBarToLeft)]
-
+            input = [(SpecialKey KeyRight, StillDown, moveBarToRight)
+                    ,(SpecialKey KeyLeft,  StillDown, moveBarToLeft)
+                    ]
         funInit winConfig gameMap [bar,ball] () initScore input gameCycle (Timer 30) bmpList
 
-createBall :: PongObject
+createBall :: GameObject ()
 createBall = let ballPic = Basic (Circle 6.0 0.0 1.0 0.0 Filled)
 	     in object "ball" ballPic False (w/2,h/2) (-8,8) ()
 
 
-createBar :: PongObject
+createBar :: GameObject ()
 createBar = let barBound = [(-25,-6),(25,-6),(25,6),(-25,6)]
                 barPic = Basic (Polyg barBound 1.0 1.0 1.0 Filled)
             in object "bar" barPic False (w/2,30) (0,0) ()
 
-moveBarToRight :: PongAction ()
-moveBarToRight = do
+moveBarToRight :: Modifiers -> Position -> IOGame GameAttribute () () () ()
+moveBarToRight mods pos = do
         obj <- findObject "bar" "barGroup"
         (pX,pY) <- getObjectPosition obj
         (sX,_)  <- getObjectSize obj
@@ -57,8 +54,8 @@
         	then (setObjectPosition ((pX + 5),pY) obj)
         	else (setObjectPosition ((w - (sX/2)),pY) obj)
 
-moveBarToLeft :: PongAction ()
-moveBarToLeft = do
+moveBarToLeft :: Modifiers -> Position -> IOGame GameAttribute () () () ()
+moveBarToLeft mods pos = do
         obj <- findObject "bar" "barGroup"
         (pX,pY) <- getObjectPosition obj
         (sX,_)  <- getObjectSize obj
@@ -66,7 +63,7 @@
         	then (setObjectPosition ((pX - 5),pY) obj)
         	else (setObjectPosition (sX/2,pY) obj)
 
-gameCycle :: PongAction ()
+gameCycle :: IOGame GameAttribute () () () ()
 gameCycle = do
         (Score n) <- getGameAttribute
         printOnScreen (show n) TimesRoman24 (0,0) 1.0 1.0 1.0
diff --git a/examples/worms/worms.hs b/examples/worms/worms.hs
--- a/examples/worms/worms.hs
+++ b/examples/worms/worms.hs
@@ -124,26 +124,26 @@
     | (tMin > tMax) = []
     | otherwise = (object ("tail" ++ (show tMin)) pic True (0,0) (0,0) (Tail 0)):(createAsleepTails (tMin + 1) tMax pic)
 
-turnLeft :: WormsAction ()
-turnLeft = do
+turnLeft :: Modifiers -> Position -> WormsAction ()
+turnLeft _ _ = do
     snakeHead <- findObject "head" "head"
     setObjectCurrentPicture 8 snakeHead
     setObjectSpeed (-speedMod,0) snakeHead
     
-turnRight :: WormsAction ()
-turnRight = do
+turnRight :: Modifiers -> Position -> WormsAction ()
+turnRight _ _ = do
     snakeHead <- findObject "head" "head"
     setObjectCurrentPicture 7 snakeHead
     setObjectSpeed (speedMod,0) snakeHead
 
-turnUp :: WormsAction ()
-turnUp = do
+turnUp :: Modifiers -> Position -> WormsAction ()
+turnUp _ _ = do
     snakeHead <- findObject "head" "head"
     setObjectCurrentPicture 5 snakeHead
     setObjectSpeed (0,speedMod) snakeHead
 
-turnDown :: WormsAction ()
-turnDown = do
+turnDown :: Modifiers -> Position -> WormsAction ()
+turnDown _ _ = do
     snakeHead <- findObject "head" "head"
     setObjectCurrentPicture 6 snakeHead
     setObjectSpeed (0,-speedMod) snakeHead
