Add speed slider, new HeronLX with deltaMs as double
[SugarCubes.git] / _Internals.pde
index 5c3f7cd5907431266f2d545637eaf83f0b617b5e..d4a5fcc76159767c41cf2a88aeffb3ff5e109c69 100644 (file)
@@ -40,28 +40,36 @@ final float TRAILER_DEPTH = 97;
 final float TRAILER_HEIGHT = 33;
 
 int targetFramerate = 60;
-
 int startMillis, lastMillis;
+
+// Core engine variables
 GLucose glucose;
 HeronLX lx;
-MappingTool mappingTool;
 LXPattern[] patterns;
-LXTransition[] transitions;
-LXEffect[] effects;
+MappingTool mappingTool;
 PandaDriver[] pandaBoards;
+final List<MidiListener> midiListeners = new ArrayList<MidiListener>();
+
+// Display configuration mode
 boolean mappingMode = false;
 boolean debugMode = false;
 DebugUI debugUI;
-String displayMode;
+boolean uiOn = true;
+LXPattern restoreToPattern = null;
 
+// Handles to UI objects
 UIContext[] overlays;
 UIPatternDeck uiPatternA;
+UICrossfader uiCrossfader;
 UIMapping uiMapping;
 UIDebugText uiDebugText;
 
 // Camera variables
 float eyeR, eyeA, eyeX, eyeY, eyeZ, midX, midY, midZ;
 
+/**
+ * Engine construction and initialization.
+ */
 LXPattern[] _patterns(GLucose glucose) {
   LXPattern[] patterns = patterns(glucose);
   for (LXPattern p : patterns) {
@@ -70,6 +78,12 @@ LXPattern[] _patterns(GLucose glucose) {
   return patterns;
 }
 
+void logTime(String evt) {
+  int now = millis();
+  println(evt + ": " + (now - lastMillis) + "ms");
+  lastMillis = now;
+}
+
 void setup() {
   startMillis = lastMillis = millis();
 
@@ -88,13 +102,12 @@ void setup() {
   
   // Set the patterns
   Engine engine = lx.engine;
-  glucose.setTransitions(transitions = transitions(glucose));
-  logTime("Built transitions");
   engine.setPatterns(patterns = _patterns(glucose));
   engine.addDeck(_patterns(glucose));
-  engine.getDeck(1).setBlendTransition(transitions[0]);
   logTime("Built patterns");
-  glucose.lx.addEffects(effects = effects(glucose));
+  glucose.setTransitions(transitions(glucose));
+  logTime("Built transitions");
+  glucose.lx.addEffects(effects(glucose));
   logTime("Built effects");
     
   // Build output driver
@@ -111,12 +124,13 @@ void setup() {
   debugUI = new DebugUI(pandaMappings);
   overlays = new UIContext[] {
     uiPatternA = new UIPatternDeck(lx.engine.getDeck(0), "PATTERN A", 4, 4, 140, 344),
-    new UICrossfader(4, 352, 140, 212),
+    uiCrossfader = new UICrossfader(4, 352, 140, 212),
+    new UIOutput(4, 568, 140, 106),
     
     new UIPatternDeck(lx.engine.getDeck(1), "PATTERN B", width-144, 4, 140, 344),
     new UIEffects(width-144, 352, 140, 144),
     new UITempo(width-144, 498, 140, 50),
-    new UIOutput(width-144, 552, 140, 122),
+    new UISpeed(width-144, 552, 140, 50),
     
     uiDebugText = new UIDebugText(4, height-64, width-8, 44),
     uiMapping = new UIMapping(mappingTool, 4, 4, 140, 344),
@@ -125,8 +139,9 @@ void setup() {
   logTime("Built overlay UI");
     
   // MIDI devices
+  midiListeners.add(new MidiListener().setEnabled(true));
   for (MidiInputDevice d : RWMidi.getInputDevices()) {
-    d.createInput(this);
+    midiListeners.add(new MidiListener(d));
   }
   SCMidiDevices.initializeStandardDevices(glucose);
   logTime("Setup MIDI devices");
@@ -149,35 +164,80 @@ void setup() {
   println("Hit the 'p' key to toggle Panda Board output");
 }
 
-
-void controllerChangeReceived(rwmidi.Controller cc) {
-  if (debugMode) {
+public class MidiListener {
+  private boolean enabled = false;
+  private final String name;
+  
+  MidiListener(MidiInputDevice d) {
+    d.createInput(this);
+    name = d.getName();
+  }
+  
+  MidiListener() {
+    registerKeyEvent(this);
+    name = "Keyboard";
+  }
+  
+  public String getName() {
+    return name;
+  }
+  
+  public void keyEvent(KeyEvent e) {
+    if (e.getID() == KeyEvent.KEY_PRESSED) {
+      switch (e.getKeyChar()) {
+        case 'q':
+          noteOnReceived(new Note(60, 127));
+          break;
+      }
+    } else if (e.getID() == KeyEvent.KEY_RELEASED) {
+      switch (e.getKeyChar()) {
+        case 'q':
+          noteOffReceived(new Note(60, 0));
+          break;
+      }
+    }
+  }
+  
+  public MidiListener setEnabled(boolean enabled) {
+    if (enabled != this.enabled) {
+      this.enabled = enabled;
+      // notify midi UI to update
+    }
+    return this;
+  }
+  
+  void controllerChangeReceived(rwmidi.Controller cc) {
+    if (!enabled) {
+      return;
+    }
     println("CC: " + cc.toString());
   }
-}
 
-void noteOnReceived(Note note) {
-  if (debugMode) {
+  void noteOnReceived(Note note) {
+    if (!enabled) {
+      return;
+    }
     println("Note On: " + note.toString());
   }
-}
 
-void noteOffReceived(Note note) {
-  if (debugMode) {
+  void noteOffReceived(Note note) {
+    if (!enabled) {
+      return;
+    }
     println("Note Off: " + note.toString());
   }
-}
 
-void logTime(String evt) {
-  int now = millis();
-  println(evt + ": " + (now - lastMillis) + "ms");
-  lastMillis = now;
 }
 
+/**
+ * Core render loop and drawing functionality.
+ */
 void draw() {
   // Draws the simulation and the 2D UI overlay
   background(40);
-  color[] colors = glucose.getColors();;
+  color[] colors = glucose.getColors();
+
+  String displayMode = uiCrossfader.getDisplayMode();
   if (displayMode == "A") {
     colors = lx.engine.getDeck(0).getColors();
   } else if (displayMode == "B") {
@@ -385,9 +445,9 @@ void drawUI() {
   }
 }
 
-boolean uiOn = true;
-LXPattern restoreToPattern = null;
-
+/**
+ * Top-level keyboard event handling
+ */
 void keyPressed() {
   if (mappingMode) {
     mappingTool.keyPressed(uiMapping);
@@ -414,7 +474,10 @@ void keyPressed() {
         lx.setPatterns(new LXPattern[] { mappingTool });
       } else {
         lx.setPatterns(patterns);
+        LXTransition pop = restoreToPattern.getTransition();
+        restoreToPattern.setTransition(null);
         lx.goPattern(restoreToPattern);
+        restoreToPattern.setTransition(pop);
       }
       break;
     case 'p':
@@ -428,6 +491,9 @@ void keyPressed() {
   }
 }
 
+/**
+ * Top-level mouse event handling
+ */
 int mx, my;
 void mousePressed() {
   boolean debugged = false;
@@ -464,8 +530,6 @@ void mouseReleased() {
   for (UIContext context : overlays) {
     context.mouseReleased(mouseX, mouseY);
   }
-
-  // ui.mouseReleased();
 }
  
 void mouseWheel(int delta) {