          :next-display (vec (for [_ (range 4)] (byte-array (take 68 (repeat 32)))))
          :last-text-buttons (atom {})
          :next-text-buttons (atom {})
-         :metronome-mode (atom {:showing true})
+         :last-top-pads (int-array 8)
+         :next-top-pads (int-array 8)
+         :metronome-mode (atom {})
          :shift-mode (atom false)
          :midi-handler (atom nil)
          :tap-tempo-handler (amidi/create-tempo-tap-handler (:metronome show))
-         }]
+         :overlays (atom (sorted-map-by >))
+         :next-overlay (atom 0)}]
     (reset! (:midi-handler controller) (partial midi-received controller))
     (clear-interface controller)
     (welcome-animation controller)

                 (button-state button state color-key))]
     (midi/midi-control (:port-out controller) (:control button) state))))

(defn track-select-state
  "Calculate the numeric value that corresponds to a particular
  named state for the specified top-row pad, and (if supplied),
  named color."
  ([x state]
   (track-select-state x state :amber))
  ([x state color-key]
   {:pre [(<= 0 x 7)]}
   (let [base-value ((keyword state) monochrome-button-states)
         color-shift (or (when-not (= state :off)
                           ((keyword color-key) color-button-colors))
                         0)]
     (+ base-value color-shift))))

(defn set-track-select-state
  "Set one of the top-row pads to a particular state and color.
  If state is already a number, it is used as-is, otherwise it is
  calculated using track-select-state."
  ([controller x state]
   (set-track-select-state controller x state :amber))
  ([controller x state color-key]
   {:pre [(<= 0 x 7)]}
   (let [state (if (number? state)
                 state
                 (track-select-state x state color-key))]
     (midi/midi-control (:port-out controller) (+ x 20) state))))

(defn set-scene-launch-color
  "Set the color of one of the 8 scene-launch touch pads (right above
  the 8x8 pad of larger, velocity sensitive, pads) to the closest
  approximation available for a desired color."
  [controller x color]

     (- val 128)
     val))

(defn- overlay-handled?
  "See if there is an interface overlay active which wants to consume
  this message; if so, send it, and see if the overlay consumes it.
  Returns truthy if an overlay consumed the message, and it should
  not be given to anyone else."
  [controller message]
  (case (:command message)
    (:note-on :note-off)
    (some (fn [[k overlay]]
            (when (contains? (captured-notes overlay) (:note message))
              (let [result (if (= :note-on (:command message))
                             (handle-note-on overlay controller message)
                             (handle-note-off overlay controller message))]
                (when (= result :done)
                  (swap! (:overlays controller) dissoc k))
                result)))
          (seq @(:overlays controller)))

    :control-change
    (some (fn [[k overlay]]
            (when (contains? (captured-controls overlay) (:note message))
              (let [result (handle-control-change overlay controller message)]
                (when (= result :done)
                  (swap! (:overlays controller) dissoc k))
                result)))
          (seq @(:overlays controller)))

    ;; Nothing we process
    false))

(defn- control-change-received
  "Process a control change message which was not handled by an
  interface overlay."
  [controller message]
  (case (:note message)
    3 ; Tap tempo button
    (when (> (:velocity message) 0)
      (interpret-tempo-tap controller)
      (enter-metronome-showing controller))

    9 ; Metronome button
    (when (> (:velocity message) 0)
      (enter-metronome-showing controller))

    14 ; Beat encoder
    (let [delta (sign-velocity (:velocity message))
