 
   (go
     (loop []
-      (let [cs [(timeout (get-level-speed (:level @state))) 
-                pause-grav]                 ; channels to listen to (timeout, pause)
+      (let [soft-speed 25
+            level-speed (get-level-speed (:level @state))
+            speed (if (:soft-drop @state)
+                    (min soft-speed level-speed)
+                    level-speed)
+
+            cs [(timeout speed) pause-grav] ; channels to listen to (timeout, pause)
             [_ c] (alts! cs)]               ; get the first channel to receive a value
         (if (= pause-grav c)                ; if "pause" received, wait for "resume"
           (<! resume-grav)
-          (try-gravity!))
+          (apply-gravity!))
         (recur)))))
 
 ;;------------------------------------------------------------
 ;; Input-driven STATE CHANGES
 ;;------------------------------------------------------------
-
-(def key-codes {:left 37
-                :up 38
-                :right 39
-                :down 40
-                :space 32
-                :shift 16})
 
 (defn try-move!
   "Try moving the current piece to the given offset."

(defn add-key-events
  "Add all the key inputs."
  []
  (.addEventListener js/window "keydown"
     (fn [e]
       (if (:piece @state)
         (let [code (aget e "keyCode")]
          (cond
            (= code (:down key-codes))  (do (try-move!  0  1) (.preventDefault e))
            (= code (:left key-codes))  (do (try-move! -1  0) (.preventDefault e))
            (= code (:right key-codes)) (do (try-move!  1  0) (.preventDefault e))
            (= code (:space key-codes)) (do (hard-drop!)      (.preventDefault e))
            (= code (:up key-codes))    (do (try-rotate!)     (.preventDefault e))))))
        )
  (.addEventListener js/window "keyup"
     (fn [e]
       (let [code (aget e "keyCode")]
         (cond
           (= code (:shift key-codes)) (toggle-record!))))))

;;------------------------------------------------------------
;; Facilities

  (let [[x y] (:position @state)
        piece (:piece @state)
        board (:board @state)]
    (swap! state assoc :board (write-piece-to-board piece x y board)
                       :piece nil
                       :soft-drop false)
    (put! pause-grav 0)

    ; If collapse routine returns a channel...
