diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,8 +1,68 @@
 # Animate Preview
 
-## OSX build
+## Usage
 
 ```
+Usage: animate-preview --target STRING [--image STRING] [--high-dpi] [--fps INT]
+                       [--watch]
+
+Available options:
+  -h,--help                Show this help text
+  --target STRING          File path with sprite information (YAML or JSON)
+  --image STRING           Force sprite sheet's file path
+  --high-dpi               Use high DPI (if available)
+  --fps INT                Force frames per second (default: 60)
+  --watch                  Watch target and image files. Automatically reload
+                           files when changed
+```
+
+## Commands
+
+### General
+
+* `m`: Toggle modes - `Playback` and `Stepper`
+* `r`: Reload sprite information and sprite sheet
+* `escape`: Quit program
+
+### Movement
+
+* `j`/`down arrow`: Move sprite down
+* `k`/`up arrow`: Move sprite up
+* `h`/`left arrow`: Move sprite left
+* `l`/`right arrow`: Move sprite right
+* `mouse click` (and drag): Sprite follows mouse cursor 
+* `c`: Center sprite
+
+### Keyframe
+
+* `n`: Next keyframe animation
+* `p`: Previous keyframe animation
+
+### Speed and Frame position
+
+* `f`: (`Playback` Mode) Increase sprite animation speed. (`Stepper` Mode) Go to next frame.
+* `d`: (`Playback` Mode) Decrease sprite animation speed. (`Stepper` Mode) Go to previous frame.
+* `a`: Reset animation speed to 1x
+
+### Scaling
+
+* `s`/`mouse wheel click`: Reset sprite scale to 1x
+* `+`/`scroll in`: Scale up sprite
+* `-`/`scroll out`: Scale down sprite
+
+### Visibility
+
+* `t`: Iterate colors of the offset's crosshair (Red, Green, Blue, Cyan, Magenta, Yellow, None)  
+* `b`: Iterate colors of the background (Gray checkered, Black checkered, White checkered)
+* `o`: Iterate colors of the sprite's outline (Red, Green, Blue, Cyan, Magenta, Yellow, None)
+* `i`: Toggle showing or hiding animation information
+
+
+## Build
+
+### OSX build
+
+```
 brew install sdl2
 brew install sdl2_ttf
 brew install sdl2_image
@@ -10,14 +70,14 @@
 stack build
 ```
 
-## Ubuntu build
+### Ubuntu build
 
 ```
 sudo apt install libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev libsdl2-gfx-dev
 stack build
 ```
 
-## Windows build
+### Windows build
 
 ```
 stack exec -- pacman -S mingw64/mingw-w64-x86_64-pkg-config mingw64/mingw-w64-x86_64-SDL2 mingw64/mingw-w64-x86_64-SDL2_ttf mingw64/mingw-w64-x86_64-SDL2_image mingw64/mingw-w64-x86_64-SDL2_gfx
diff --git a/animate-preview.cabal b/animate-preview.cabal
--- a/animate-preview.cabal
+++ b/animate-preview.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 51d99c14d61a1d85be7c9e79e08619cb9077082c77d374d45595f5a1cc88b81e
+-- hash: 2a1075ed97cba266dad033a75687619badc2e94f4ab5168ea900c407645a82ff
 
 name:           animate-preview
-version:        0.0.0
+version:        0.1.0
 synopsis:       Preview tool for sprite animation
 description:    Preview tool for sprite animation
 category:       Game
@@ -65,7 +65,6 @@
       Animate.Preview.Animation
       Animate.Preview.Color
       Animate.Preview.Config
-      Animate.Preview.Frame
       Animate.Preview.Input
       Animate.Preview.Loader
       Animate.Preview.Logger
diff --git a/library/Animate/Preview.hs b/library/Animate/Preview.hs
--- a/library/Animate/Preview.hs
+++ b/library/Animate/Preview.hs
@@ -33,11 +33,11 @@
 import Animate.Preview.Timer
 
 data Options = Options
-  { target :: String  <?> "file path with sprite data (YAML or JSON)"
-  , image :: (Maybe String) <?> "Force sprite sheet image path"
-  , scale :: (Maybe Float) <?> "Scale the sprite size"
-  , highDpi :: Bool <?> "Use high DPI"
-  , watch :: Bool <?> "Watch files and reload on change"
+  { target :: String  <?> "File path with sprite information (YAML or JSON)"
+  , image :: (Maybe String) <?> "Force sprite sheet's file path"
+  , highDpi :: Bool <?> "Use high DPI (if available)"
+  , fps :: (Maybe Int) <?> "Force frames per second (default: 60)"
+  , watch :: Bool <?> "Watch target and image files. Automatically reload files when changed"
   } deriving (Show, Generic)
 
 instance ParseRecord Options where
@@ -47,6 +47,7 @@
 main = do
   options <- getRecord "options"
   let highDpi' = unHelpful $ highDpi options
+  let fps' = max 1 (fromMaybe 60 (unHelpful $ fps options))
 
   SDL.initialize [SDL.InitVideo]
   Font.initialize
@@ -67,7 +68,6 @@
   let settings = Settings
         { sTarget = unHelpful $ target options
         , sSpritesheet = unHelpful $ image options
-        , sScale = fromMaybe 1 (unHelpful $ scale options)
         }
 
   let cfg = Config
@@ -78,6 +78,8 @@
         , cSettings = settings
         , cCurrent = current
         , cLoaded = loaded
+        , cFps = fps'
+        , cFrameDeltaSeconds = 1.0 / fromIntegral fps'
         }
 
   when (unHelpful $ watch options) $ do
diff --git a/library/Animate/Preview/Config.hs b/library/Animate/Preview/Config.hs
--- a/library/Animate/Preview/Config.hs
+++ b/library/Animate/Preview/Config.hs
@@ -13,7 +13,6 @@
 data Settings = Settings
   { sTarget :: String
   , sSpritesheet :: Maybe String
-  , sScale :: Float
   }
 
 data Loaded = Loaded
@@ -36,6 +35,8 @@
   , cSettings :: Settings
   , cCurrent :: MVar (Maybe Current)
   , cLoaded :: MVar (Maybe Loaded)
+  , cFps :: Int
+  , cFrameDeltaSeconds :: Seconds
   }
 
 type R m = MonadReader Config m
diff --git a/library/Animate/Preview/Frame.hs b/library/Animate/Preview/Frame.hs
deleted file mode 100644
--- a/library/Animate/Preview/Frame.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-module Animate.Preview.Frame where
-
-frameDeltaSeconds :: Fractional a => a
-frameDeltaSeconds = 0.016667
-
-frameDeltaMilliseconds :: Int
-frameDeltaMilliseconds = 16
-
-msps, fps :: Int
-msps = 1000
-fps = 60
diff --git a/library/Animate/Preview/Scene.hs b/library/Animate/Preview/Scene.hs
--- a/library/Animate/Preview/Scene.hs
+++ b/library/Animate/Preview/Scene.hs
@@ -15,7 +15,6 @@
 import Animate.Preview.Config
 import Animate.Preview.Renderer
 import Animate.Preview.Input
-import Animate.Preview.Frame
 import Animate.Preview.State
 import Animate.Preview.ManagerInput
 import Animate.Preview.Color
@@ -105,6 +104,7 @@
 updateAnimation = do
   mode <- gets vMode
   loaded' <- getLoaded 
+  frameDeltaSeconds <- asks cFrameDeltaSeconds
   case loaded' of
     Nothing -> return ()
     Just loaded -> do
@@ -244,6 +244,7 @@
   current <- getCurrent
   originColor <- gets vOriginColor
   outlineColor <- gets vOutlineColor
+  fps <- asks cFps
   accel <- gets vAccel
   mode <- gets vMode
   infoShown <- gets vInfoShown
@@ -254,15 +255,15 @@
   let lineSpacing = lineSpacing' highDpi
   case loaded' of
     Nothing -> when infoShown $ do
-      drawText (ofsX, ofsY + lineSpacing * 4)  $ toText $ concat ["Anim:"]
-      drawText (ofsX, ofsY + lineSpacing * 5)  $ toText $ concat ["  Key:"]
-      drawText (ofsX, ofsY + lineSpacing * 6)  $ toText $ concat ["  Time:"]
-      drawText (ofsX, ofsY + lineSpacing * 7)  $ toText $ concat ["Pos:"]
-      drawText (ofsX, ofsY + lineSpacing * 8)  $ toText $ concat ["  Frame:"]
-      drawText (ofsX, ofsY + lineSpacing * 9)  $ toText $ concat ["  Time:"]
-      drawText (ofsX, ofsY + lineSpacing * 10) $ toText $ concat ["  Points:"]
-      drawText (ofsX, ofsY + lineSpacing * 11) $ toText $ concat ["  Size:"]
-      drawText (ofsX, ofsY + lineSpacing * 12) $ toText $ concat ["  Offset: "]
+      drawText (ofsX, ofsY + lineSpacing * 5)  $ toText $ concat ["Anim:"]
+      drawText (ofsX, ofsY + lineSpacing * 6)  $ toText $ concat ["  Key:"]
+      drawText (ofsX, ofsY + lineSpacing * 7)  $ toText $ concat ["  Time:"]
+      drawText (ofsX, ofsY + lineSpacing * 8)  $ toText $ concat ["Pos:"]
+      drawText (ofsX, ofsY + lineSpacing * 9)  $ toText $ concat ["  Frame:"]
+      drawText (ofsX, ofsY + lineSpacing * 10)  $ toText $ concat ["  Time:"]
+      drawText (ofsX, ofsY + lineSpacing * 11) $ toText $ concat ["  Points:"]
+      drawText (ofsX, ofsY + lineSpacing * 12) $ toText $ concat ["  Size:"]
+      drawText (ofsX, ofsY + lineSpacing * 13) $ toText $ concat ["  Offset: "]
     Just loaded -> do
       case current of
         Nothing -> return ()
@@ -282,15 +283,15 @@
           drawAniSprite (lSpriteSheet loaded) outlineColor scalar loc (x, y)
           when infoShown $ do
             let keyName = cKeyName c
-            drawText (ofsX, ofsY + lineSpacing * 4)  $ toText $ concat ["Anim:"]
-            drawText (ofsX, ofsY + lineSpacing * 5)  $ toText $ concat ["  Key: \"", fromText keyName, "\" ", show $ Animate.pKey pos, " [", show $ lTotalKeys loaded - 1, "]"]
-            drawText (ofsX, ofsY + lineSpacing * 6)  $ toText $ concat ["  Time: ", show totalSeconds]
-            drawText (ofsX, ofsY + lineSpacing * 7)  $ toText $ concat ["Pos:"]
-            drawText (ofsX, ofsY + lineSpacing * 8)  $ toText $ concat ["  Frame: ", show $ Animate.pFrameIndex pos,  " [", show $ framesLen - 1, "]"]
-            drawText (ofsX, ofsY + lineSpacing * 9)  $ toText $ concat ["  Time: ", show $ Animate.pCounter pos, " [", show $ frameDelay, "]"]
-            drawText (ofsX, ofsY + lineSpacing * 10) $ toText $ concat ["  Points: (", show x0, ",", show y0, ") (", show x1, ",", show y1, ")"]
-            drawText (ofsX, ofsY + lineSpacing * 11) $ toText $ concat ["  Size: (", show w, ",", show h, ")"]
-            drawText (ofsX, ofsY + lineSpacing * 12) $ toText $ concat $ ["  Offset: "] ++ case Animate.scOffset frameClip of
+            drawText (ofsX, ofsY + lineSpacing * 5)  $ toText $ concat ["Anim:"]
+            drawText (ofsX, ofsY + lineSpacing * 6)  $ toText $ concat ["  Key: \"", fromText keyName, "\" ", show $ Animate.pKey pos, " [", show $ lTotalKeys loaded - 1, "]"]
+            drawText (ofsX, ofsY + lineSpacing * 7)  $ toText $ concat ["  Time: ", show totalSeconds]
+            drawText (ofsX, ofsY + lineSpacing * 8)  $ toText $ concat ["Pos:"]
+            drawText (ofsX, ofsY + lineSpacing * 9)  $ toText $ concat ["  Frame: ", show $ Animate.pFrameIndex pos,  " [", show $ framesLen - 1, "]"]
+            drawText (ofsX, ofsY + lineSpacing * 10)  $ toText $ concat ["  Time: ", show $ Animate.pCounter pos, " [", show $ frameDelay, "]"]
+            drawText (ofsX, ofsY + lineSpacing * 11) $ toText $ concat ["  Points: (", show x0, ",", show y0, ") (", show x1, ",", show y1, ")"]
+            drawText (ofsX, ofsY + lineSpacing * 12) $ toText $ concat ["  Size: (", show w, ",", show h, ")"]
+            drawText (ofsX, ofsY + lineSpacing * 13) $ toText $ concat $ ["  Offset: "] ++ case Animate.scOffset frameClip of
               Nothing -> []
               Just (ox,oy) -> ["(", show ox, ",", show oy, ")"]
   case originColor of
@@ -301,8 +302,9 @@
     settings <- asks cSettings
     drawText (ofsX, ofsY + lineSpacing * 0) ("Mode: " `mappend` if mode == Mode'Playback then "Playback" else "Stepper")
     drawText (ofsX, ofsY + lineSpacing * 1) ("File: " `mappend` toText (sTarget settings))
-    drawText (ofsX, ofsY + lineSpacing * 2) ("Scale: " `mappend` toText (asScaleString scale))
-    drawText (ofsX, ofsY + lineSpacing * 3) ("Accel: " `mappend` toText (asSpeedString accel))
+    drawText (ofsX, ofsY + lineSpacing * 2) ("FPS: " `mappend` toText (show fps))
+    drawText (ofsX, ofsY + lineSpacing * 3) ("Scale: " `mappend` toText (asScaleString scale))
+    drawText (ofsX, ofsY + lineSpacing * 4) ("Accel: " `mappend` toText (asSpeedString accel))
   where
     lineSpacing' x = if x then 26 else 13
     ofsX = 6
diff --git a/library/Animate/Preview/Timer.hs b/library/Animate/Preview/Timer.hs
--- a/library/Animate/Preview/Timer.hs
+++ b/library/Animate/Preview/Timer.hs
@@ -3,8 +3,9 @@
 import qualified SDL
 import Control.Monad.IO.Class (MonadIO(..))
 import Control.Monad (when)
+import Control.Monad.Reader (asks)
 
-import Animate.Preview.Frame
+import Animate.Preview.Config
 
 class Monad m => Timer m where
   startTicks :: m Int
@@ -12,8 +13,12 @@
   startTicks = fromIntegral <$> liftIO SDL.ticks
 
   delayTicks :: Int -> m ()
-  default delayTicks :: MonadIO m => Int -> m ()
-  delayTicks start = liftIO $ do
-    end <- fromIntegral <$> SDL.ticks
-    let ms = (msps - (end -start) * fps) `div` fps
-    when (ms > 0) (SDL.delay $ fromIntegral ms)
+  default delayTicks :: (MonadIO m, R m) => Int -> m ()
+  delayTicks start = do
+    fps <- asks cFps
+    liftIO $ do
+      end <- fromIntegral <$> SDL.ticks
+      let ms = (msps - (end -start) * fps) `div` fps
+      when (ms > 0) (SDL.delay $ fromIntegral ms)
+    where
+      msps = 1000
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: animate-preview
-version: '0.0.0'
+version: '0.1.0'
 github: jxv/animate-preview
 license: BSD3
 category: Game
