diff --git a/Launchpad PasswortMaster.sln b/Launchpad PasswortMaster.sln
new file mode 100644
index 0000000..3adb674
--- /dev/null
+++ b/Launchpad PasswortMaster.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Launchpad PasswortMaster", "Launchpad PasswortMaster\Launchpad PasswortMaster.csproj", "{7E3C8B4B-791D-4AAB-982B-858952CAF172}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "launchpad-dot-net", "..\..\Launchpad Coding Tests\launchpad-dot-net-master\launchpad-dot-net\launchpad-dot-net.csproj", "{2784C4AF-3B96-471B-91B0-1A11C342D375}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7E3C8B4B-791D-4AAB-982B-858952CAF172}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7E3C8B4B-791D-4AAB-982B-858952CAF172}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7E3C8B4B-791D-4AAB-982B-858952CAF172}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7E3C8B4B-791D-4AAB-982B-858952CAF172}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2784C4AF-3B96-471B-91B0-1A11C342D375}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2784C4AF-3B96-471B-91B0-1A11C342D375}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2784C4AF-3B96-471B-91B0-1A11C342D375}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2784C4AF-3B96-471B-91B0-1A11C342D375}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Launchpad PasswortMaster/App.config b/Launchpad PasswortMaster/App.config
new file mode 100644
index 0000000..d740e88
--- /dev/null
+++ b/Launchpad PasswortMaster/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Launchpad PasswortMaster/Launchpad PasswortMaster.csproj b/Launchpad PasswortMaster/Launchpad PasswortMaster.csproj
new file mode 100644
index 0000000..9871798
--- /dev/null
+++ b/Launchpad PasswortMaster/Launchpad PasswortMaster.csproj
@@ -0,0 +1,66 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {7E3C8B4B-791D-4AAB-982B-858952CAF172}
+ Exe
+ Properties
+ Launchpad_PasswortMaster
+ Launchpad PasswortMaster
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {2784c4af-3b96-471b-91b0-1a11c342d375}
+ launchpad-dot-net
+
+
+
+
+
\ No newline at end of file
diff --git a/Launchpad PasswortMaster/Program.cs b/Launchpad PasswortMaster/Program.cs
new file mode 100644
index 0000000..5f2121e
--- /dev/null
+++ b/Launchpad PasswortMaster/Program.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using LaunchpadNET;
+
+namespace Launchpad_PasswortMaster
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Interface LaunchInterface = new Interface();
+ LaunchpadNET.Interface.LaunchpadDevice Device = new Interface.LaunchpadDevice("Meins");
+
+ LaunchInterface.connect(LaunchInterface.getConnectedLaunchpads()[0]); //Connects with your Launchpad
+
+ LaunchInterface.clearAllLEDs();
+ int veloCount = 1;
+ //for (int indexerX = 0; indexerX < 8; indexerX++)
+ //{
+ //for (int indexerY = 0; indexerY < 8; indexerY++)
+ //{
+ LaunchInterface.setLED(3,0, 1);
+ //}
+
+ //}
+
+
+
+ Console.ReadLine();
+ LaunchInterface.clearAllLEDs();
+ }
+ }
+}
diff --git a/Launchpad PasswortMaster/Properties/AssemblyInfo.cs b/Launchpad PasswortMaster/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..efbf39b
--- /dev/null
+++ b/Launchpad PasswortMaster/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("Launchpad PasswortMaster")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Orgname")]
+[assembly: AssemblyProduct("Launchpad PasswortMaster")]
+[assembly: AssemblyCopyright("Copyright © Orgname 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
+// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("7e3c8b4b-791d-4aab-982b-858952caf172")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/launchpad-dot-net-master/.gitattributes b/launchpad-dot-net-master/.gitattributes
new file mode 100644
index 0000000..bdb0cab
--- /dev/null
+++ b/launchpad-dot-net-master/.gitattributes
@@ -0,0 +1,17 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
diff --git a/launchpad-dot-net-master/.gitignore b/launchpad-dot-net-master/.gitignore
new file mode 100644
index 0000000..cd2946a
--- /dev/null
+++ b/launchpad-dot-net-master/.gitignore
@@ -0,0 +1,47 @@
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# =========================
+# Operating System Files
+# =========================
+
+# OSX
+# =========================
+
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
diff --git a/launchpad-dot-net-master/README.md b/launchpad-dot-net-master/README.md
new file mode 100644
index 0000000..729a626
--- /dev/null
+++ b/launchpad-dot-net-master/README.md
@@ -0,0 +1,18 @@
+# Launchpad.NET
+*The easy way to create applications for the NOVATION Launchpad*
+
+**Welcome to LAUNCHPAD.NET**
+This is a simple C# library which allows you to interact with the NOVATION LAUNCHPAD.
+You can view the GitHub Wiki over here, in order to learn how the functions work together.
+This is only possible because of **jstnryan** and his https://github.com/jstnryan/midi-dot-net
+
+**Features**
+This comes with a few features right now, but I will extend this in the future!
+ + Automatic MIDI Device sorting (you only see Launchpads, not other MIDI devices
+ + Easy LED state setting (set LEDs only giving coordinates and velocity)
+ + LED rect filling (with start and end coordinates)
+ + Easy handling of Launchpads with a own class for Launchpad
+ + Easy connecting / disconnecting
+
+**Bugs?**
+No problem, thats why GitHub is here. :joy:
diff --git a/launchpad-dot-net-master/launchpad-dot-net-master.zip b/launchpad-dot-net-master/launchpad-dot-net-master.zip
new file mode 100644
index 0000000..775abe8
Binary files /dev/null and b/launchpad-dot-net-master/launchpad-dot-net-master.zip differ
diff --git a/launchpad-dot-net-master/launchpad-dot-net.sln b/launchpad-dot-net-master/launchpad-dot-net.sln
new file mode 100644
index 0000000..3a0d645
--- /dev/null
+++ b/launchpad-dot-net-master/launchpad-dot-net.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 14 for Windows Desktop
+VisualStudioVersion = 14.0.23107.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "launchpad-dot-net", "launchpad-dot-net\launchpad-dot-net.csproj", "{2784C4AF-3B96-471B-91B0-1A11C342D375}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2784C4AF-3B96-471B-91B0-1A11C342D375}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2784C4AF-3B96-471B-91B0-1A11C342D375}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2784C4AF-3B96-471B-91B0-1A11C342D375}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2784C4AF-3B96-471B-91B0-1A11C342D375}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/launchpad-dot-net-master/launchpad-dot-net/Interface.cs b/launchpad-dot-net-master/launchpad-dot-net/Interface.cs
new file mode 100644
index 0000000..6e2718c
--- /dev/null
+++ b/launchpad-dot-net-master/launchpad-dot-net/Interface.cs
@@ -0,0 +1,374 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Midi;
+
+namespace LaunchpadNET
+{
+ public class Interface
+ {
+ private Pitch[,] notes = new Pitch[8, 8] {
+ { Pitch.A5, Pitch.ASharp5, Pitch.B5, Pitch.C6, Pitch.CSharp6, Pitch.D6, Pitch.DSharp6, Pitch.E6 },
+ { Pitch.B4, Pitch.C5, Pitch.CSharp5, Pitch.D5, Pitch.DSharp5, Pitch.E5, Pitch.F5, Pitch.FSharp5 },
+ { Pitch.CSharp4, Pitch.D4, Pitch.DSharp4, Pitch.E4, Pitch.F4, Pitch.FSharp4, Pitch.G4, Pitch.GSharp4 },
+ { Pitch.DSharp3, Pitch.E3, Pitch.F3, Pitch.FSharp3, Pitch.G3, Pitch.GSharp3, Pitch.A3, Pitch.ASharp3 },
+ { Pitch.F2, Pitch.FSharp2, Pitch.G2, Pitch.GSharp2, Pitch.A2, Pitch.ASharp2, Pitch.B2, Pitch.C3 },
+ { Pitch.G1, Pitch.GSharp1, Pitch.A1, Pitch.ASharp1, Pitch.B1, Pitch.C2, Pitch.CSharp2, Pitch.D2 },
+ { Pitch.A0, Pitch.ASharp0, Pitch.B0, Pitch.C1, Pitch.CSharp1, Pitch.D1, Pitch.DSharp1, Pitch.E1 },
+ { Pitch.BNeg1, Pitch.C0, Pitch.CSharp0, Pitch.D0, Pitch.DSharp0, Pitch.E0, Pitch.F0, Pitch.FSharp0 }
+ };
+
+ private Pitch[] rightLEDnotes = new Pitch[] {
+ Pitch.F6, Pitch.G5, Pitch.A4, Pitch.B3, Pitch.CSharp3, Pitch.DSharp2, Pitch.F1, Pitch.G0
+ };
+
+ public InputDevice targetInput;
+ public OutputDevice targetOutput;
+
+ public delegate void LaunchpadKeyEventHandler(object source, LaunchpadKeyEventArgs e);
+
+ public delegate void LaunchpadCCKeyEventHandler(object source, LaunchpadCCKeyEventArgs e);
+
+ ///
+ /// Event Handler when a Launchpad Key is pressed.
+ ///
+ public event LaunchpadKeyEventHandler OnLaunchpadKeyPressed;
+ public event LaunchpadCCKeyEventHandler OnLaunchpadCCKeyPressed;
+
+ public class LaunchpadCCKeyEventArgs : EventArgs
+ {
+ private int val;
+ public LaunchpadCCKeyEventArgs(int _val)
+ {
+ val = _val;
+ }
+ public int GetVal()
+ {
+ return val;
+ }
+ }
+
+ ///
+ /// EventArgs for pressed Launchpad Key
+ ///
+ public class LaunchpadKeyEventArgs : EventArgs
+ {
+ private int x;
+ private int y;
+ public LaunchpadKeyEventArgs(int _pX, int _pY)
+ {
+ x = _pX;
+ y = _pY;
+ }
+ public int GetX()
+ {
+ return x;
+ }
+ public int GetY()
+ {
+ return y;
+ }
+ }
+
+ ///
+ /// Creates a text scroll.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void createTextScroll(string text, int speed, bool looping, int velo)
+ {
+ byte[] sysexHeader = { 240, 00, 32, 41, 2, 4 };
+ byte[] sysexStop = { 247 };
+ byte operation = 20;
+
+ byte _velocity = (byte)velo;
+ byte _speed = (byte)speed;
+ byte _loop = Convert.ToByte(looping);
+ byte[] _text = { };
+
+ byte[] finalArgs = { operation, _velocity, _loop, _speed };
+
+ List charList = new List();
+ foreach(char c in text)
+ {
+ int unicode = c;
+ if (unicode < 128)
+ charList.Add(Convert.ToByte(unicode));
+ }
+ _text = charList.ToArray();
+
+ byte[] finalBytes = sysexHeader.Concat(finalArgs.Concat(_text.Concat(sysexStop))).ToArray();
+
+ targetOutput.SendSysEx(finalBytes);
+ }
+
+ public void stopLoopingTextScroll()
+ {
+ byte[] stop = { 240, 0, 32, 41, 2, 24, 20, 247 };
+ targetOutput.SendSysEx(stop);
+ }
+
+ private void sysExAnswer(SysExMessage m)
+ {
+ byte[] msg = m.Data;
+ byte[] stopBytes = { 240, 0, 32, 41, 2, 24, 21, 247 };
+ }
+
+ private void midiPress(Midi.NoteOnMessage msg)
+ {
+ if (OnLaunchpadKeyPressed != null && !rightLEDnotes.Contains(msg.Pitch))
+ {
+ OnLaunchpadKeyPressed(this, new LaunchpadKeyEventArgs(midiNoteToLed(msg.Pitch)[0], midiNoteToLed(msg.Pitch)[1]));
+ }
+ else if (OnLaunchpadKeyPressed != null && rightLEDnotes.Contains(msg.Pitch))
+ {
+ OnLaunchpadCCKeyPressed(this, new LaunchpadCCKeyEventArgs(midiNoteToSideLED(msg.Pitch)));
+ }
+ }
+
+ public int midiNoteToSideLED(Pitch p)
+ {
+ for (int y = 0; y <= 7; y++)
+ {
+ if (rightLEDnotes[y] == p)
+ {
+ return y;
+ }
+ }
+ return 0;
+ }
+
+ ///
+ /// Returns the LED coordinates of a MIdi note
+ ///
+ /// The Midi Note.
+ /// The X,Y coordinates.
+ public int[] midiNoteToLed(Pitch p)
+ {
+ for (int x = 0; x <= 7; x++)
+ {
+ for (int y = 0; y <= 7; y++)
+ {
+ if (notes[x,y] == p)
+ {
+ int[] r1 = { x, y };
+ return r1;
+ }
+ }
+ }
+ int[] r2 = { 0, 0 };
+ return r2;
+ }
+
+ ///
+ /// Returns the equilavent Midi Note to X and Y coordinates.
+ ///
+ /// The X coordinate of the LED
+ /// The Y coordinate of the LED
+ /// The midi note
+ public Pitch ledToMidiNote(int x, int y)
+ {
+ return notes[x, y];
+ }
+
+ public void clearAllLEDs()
+ {
+ for (int x = 0; x < 8; x++)
+ {
+ for (int y = 0; y < 8; y++)
+ {
+ setLED(x, y, 0);
+ }
+ }
+
+ for (int ry = 0; ry < 8; ry++)
+ {
+ setSideLED(ry, 0);
+ }
+
+ for (int tx = 1; tx < 9; tx++)
+ {
+ setTopLEDs(tx, 0);
+ }
+ }
+
+ ///
+ /// Fills Top Row LEDs.
+ ///
+ ///
+ ///
+ ///
+ public void fillTopLEDs(int startX, int endX, int velo)
+ {
+ for (int x = 1; x < 9; x++)
+ {
+ if (x >= startX && x <= endX)
+ {
+ setTopLEDs(x, velo);
+ }
+ }
+ }
+
+ ///
+ /// Fills a region of Side LEDs.
+ ///
+ ///
+ ///
+ ///
+ public void fillSideLEDs(int startY, int endY, int velo)
+ {
+ for (int y = 0; y < rightLEDnotes.Length; y++)
+ {
+ if (y >= startY && y <= endY)
+ {
+ setSideLED(y, velo);
+ }
+ }
+ }
+
+ ///
+ /// Creates a rectangular mesh of LEDs.
+ ///
+ /// Start X coordinate
+ /// Start Y coordinate
+ /// End X coordinate
+ /// End Y coordinate
+ /// Painting velocity
+ public void fillLEDs(int startX, int startY, int endX, int endY, int velo)
+ {
+ for (int x = 0; x < notes.Length; x++)
+ {
+ for (int y = 0; y < notes.Length; y++)
+ {
+ if (x >= startX && y >= startY && x <= endX && y <= endY)
+ setLED(x, y, velo);
+ }
+ }
+ }
+
+ ///
+ /// Sets a Top LED of the launchpad
+ ///
+ ///
+ ///
+ public void setTopLEDs(int x, int velo)
+ {
+ byte[] data = { 240, 0, 32, 41, 2, 24, 10, Convert.ToByte(103+x), Convert.ToByte(velo), 247 };
+ targetOutput.SendSysEx(data);
+ }
+
+ ///
+ /// Sets a Side LED of the Launchpad.
+ ///
+ /// The height of the right Side LED.
+ /// Velocity index.
+ public void setSideLED(int y, int velo)
+ {
+ targetOutput.SendNoteOn(Channel.Channel1, rightLEDnotes[y], velo);
+ }
+
+ ///
+ /// Sets a LED of the Launchpad.
+ ///
+ /// The X coordinate.
+ /// The Y coordinate.
+ /// The velocity.
+ public void setLED(int x, int y, int velo)
+ {
+ try
+ {
+ targetOutput.SendNoteOn(Channel.Channel1, notes[x, y], velo);
+ }
+ catch (Midi.DeviceException)
+ {
+ Console.WriteLine("<< LAUNCHPAD.NET >> Midi.DeviceException");
+ throw;
+ }
+ }
+
+ ///
+ /// Returns all connected and installed Launchpads.
+ ///
+ /// Returns LaunchpadDevice array.
+ public LaunchpadDevice[] getConnectedLaunchpads()
+ {
+ List tempDevices = new List();
+
+ foreach (InputDevice id in Midi.InputDevice.InstalledDevices)
+ {
+ foreach (OutputDevice od in Midi.OutputDevice.InstalledDevices)
+ {
+ if (id.Name == od.Name)
+ {
+ if (id.Name.ToLower().Contains("launchpad"))
+ {
+ tempDevices.Add(new LaunchpadDevice(id.Name));
+ }
+ }
+ }
+ }
+
+ return tempDevices.ToArray();
+ }
+
+ ///
+ /// Function to connect with a LaunchpadDevice
+ ///
+ /// The Launchpad to connect to.
+ /// Returns bool if connection was successful.
+ public bool connect(LaunchpadDevice device)
+ {
+ foreach(InputDevice id in Midi.InputDevice.InstalledDevices)
+ {
+ if (id.Name.ToLower() == device._midiName.ToLower())
+ {
+ targetInput = id;
+ id.Open();
+ targetInput.NoteOn += new InputDevice.NoteOnHandler(midiPress);
+ targetInput.StartReceiving(null);
+ }
+ }
+ foreach (OutputDevice od in Midi.OutputDevice.InstalledDevices)
+ {
+ if (od.Name.ToLower() == device._midiName.ToLower())
+ {
+ targetOutput = od;
+ od.Open();
+ }
+ }
+
+ return true; // targetInput.IsOpen && targetOutput.IsOpen;
+ }
+
+ ///
+ /// Disconnects a given LaunchpadDevice
+ ///
+ /// The Launchpad to disconnect.
+ /// Returns bool if disconnection was successful.
+ public bool disconnect(LaunchpadDevice device)
+ {
+ if (targetInput.IsOpen && targetOutput.IsOpen)
+ {
+ targetInput.StopReceiving();
+ targetInput.Close();
+ targetOutput.Close();
+ }
+ return !targetInput.IsOpen && !targetOutput.IsOpen;
+ }
+
+ public class LaunchpadDevice
+ {
+ public string _midiName;
+ //public int _midiDeviceId;
+
+ public LaunchpadDevice(string name)
+ {
+ _midiName = name;
+ }
+ }
+ }
+}
diff --git a/launchpad-dot-net-master/launchpad-dot-net/Properties/AssemblyInfo.cs b/launchpad-dot-net-master/launchpad-dot-net/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..031cc01
--- /dev/null
+++ b/launchpad-dot-net-master/launchpad-dot-net/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("launchpad-dot-net")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("launchpad-dot-net")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
+// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(true)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("2784c4af-3b96-471b-91b0-1a11c342d375")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/launchpad-dot-net-master/launchpad-dot-net/launchpad-dot-net.csproj b/launchpad-dot-net-master/launchpad-dot-net/launchpad-dot-net.csproj
new file mode 100644
index 0000000..1074635
--- /dev/null
+++ b/launchpad-dot-net-master/launchpad-dot-net/launchpad-dot-net.csproj
@@ -0,0 +1,58 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2784C4AF-3B96-471B-91B0-1A11C342D375}
+ Library
+ Properties
+ launchpad_dot_net
+ launchpad-dot-net
+ v4.5
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ False
+ bin\Debug\Midi.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/launchpad-master/.gitattributes b/launchpad-master/.gitattributes
new file mode 100644
index 0000000..412eeda
--- /dev/null
+++ b/launchpad-master/.gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
diff --git a/launchpad-master/.gitignore b/launchpad-master/.gitignore
new file mode 100644
index 0000000..5fc9ea3
--- /dev/null
+++ b/launchpad-master/.gitignore
@@ -0,0 +1,120 @@
+# App specific
+
+# OS generated files #
+######################
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+Icon?
+ehthumbs.db
+Thumbs.db
+
+# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
+[Bb]in/
+[Oo]bj/
+
+# mstest test results
+TestResults
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+.vs/
+*.suo
+*.user
+*.sln.docstates
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+x64/
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.log
+*.vspscc
+*.vssscc
+.builds
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish
+
+# Publish Web Output
+*.Publish.xml
+
+# NuGet Packages Directory
+packages
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Others
+[Bb]in
+[Oo]bj
+sql
+TestResults
+[Tt]est[Rr]esult*
+*.Cache
+ClientBin
+[Ss]tyle[Cc]op.*
+~$*
+*.dbmdl
+Generated_Code #added for RIA/Silverlight projects
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
\ No newline at end of file
diff --git a/launchpad-master/IntelOrca.Launchpad.sln b/launchpad-master/IntelOrca.Launchpad.sln
new file mode 100644
index 0000000..4c42cf2
--- /dev/null
+++ b/launchpad-master/IntelOrca.Launchpad.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntelOrca.Launchpad", "IntelOrca.Launchpad\IntelOrca.Launchpad.csproj", "{FCF77754-C985-4F3D-BE0B-E14011C5DC5B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntelOrca.LaunchpadTests", "IntelOrca.LaunchpadTests\IntelOrca.LaunchpadTests.csproj", "{C2C7FD5A-D56C-4C74-91E3-2D9F5D92FCA3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FCF77754-C985-4F3D-BE0B-E14011C5DC5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FCF77754-C985-4F3D-BE0B-E14011C5DC5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FCF77754-C985-4F3D-BE0B-E14011C5DC5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FCF77754-C985-4F3D-BE0B-E14011C5DC5B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C2C7FD5A-D56C-4C74-91E3-2D9F5D92FCA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C2C7FD5A-D56C-4C74-91E3-2D9F5D92FCA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C2C7FD5A-D56C-4C74-91E3-2D9F5D92FCA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C2C7FD5A-D56C-4C74-91E3-2D9F5D92FCA3}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/launchpad-master/IntelOrca.Launchpad/App.config b/launchpad-master/IntelOrca.Launchpad/App.config
new file mode 100644
index 0000000..8e15646
--- /dev/null
+++ b/launchpad-master/IntelOrca.Launchpad/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/launchpad-master/IntelOrca.Launchpad/ButtonPressEventArgs.cs b/launchpad-master/IntelOrca.Launchpad/ButtonPressEventArgs.cs
new file mode 100644
index 0000000..a8c15f6
--- /dev/null
+++ b/launchpad-master/IntelOrca.Launchpad/ButtonPressEventArgs.cs
@@ -0,0 +1,56 @@
+using System;
+
+namespace IntelOrca.Launchpad
+{
+ public class ButtonPressEventArgs : EventArgs
+ {
+ private ButtonType mType;
+ private ToolbarButton mToolbarButton;
+ private SideButton mSidebarButton;
+ private int mX, mY;
+
+ public ButtonPressEventArgs(ToolbarButton toolbarButton)
+ {
+ mType = ButtonType.Toolbar;
+ mToolbarButton = toolbarButton;
+ }
+
+ public ButtonPressEventArgs(SideButton sideButton)
+ {
+ mType = ButtonType.Side;
+ mSidebarButton = sideButton;
+ }
+
+ public ButtonPressEventArgs(int x, int y)
+ {
+ mType = ButtonType.Grid;
+ mX = x;
+ mY = y;
+ }
+
+ public ButtonType Type
+ {
+ get { return mType; }
+ }
+
+ public ToolbarButton ToolbarButton
+ {
+ get { return mToolbarButton; }
+ }
+
+ public SideButton SidebarButton
+ {
+ get { return mSidebarButton; }
+ }
+
+ public int X
+ {
+ get { return mX; }
+ }
+
+ public int Y
+ {
+ get { return mY; }
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.Launchpad/IntelOrca.Launchpad.csproj b/launchpad-master/IntelOrca.Launchpad/IntelOrca.Launchpad.csproj
new file mode 100644
index 0000000..36ee93f
--- /dev/null
+++ b/launchpad-master/IntelOrca.Launchpad/IntelOrca.Launchpad.csproj
@@ -0,0 +1,62 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {FCF77754-C985-4F3D-BE0B-E14011C5DC5B}
+ Library
+ Properties
+ IntelOrca.Launchpad
+ IntelOrca.Launchpad
+ v4.5
+ 512
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+ ..\packages\midi-dot-net.1.1.0\lib\net35\Midi.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/launchpad-master/IntelOrca.Launchpad/LaunchpadButton.cs b/launchpad-master/IntelOrca.Launchpad/LaunchpadButton.cs
new file mode 100644
index 0000000..86f804d
--- /dev/null
+++ b/launchpad-master/IntelOrca.Launchpad/LaunchpadButton.cs
@@ -0,0 +1,82 @@
+using Midi;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IntelOrca.Launchpad
+{
+ public enum ButtonType { Grid, Toolbar, Side }
+ public enum ButtonBrightness { Off, Low, Medium, Full };
+ public enum ButtonPressState { Up = 0, Down = 127 };
+
+ public class LaunchpadButton
+ {
+ private LaunchpadDevice mLaunchpadDevice;
+ private ButtonBrightness mRedBrightness, mGreenBrightness;
+ private ButtonPressState mState;
+
+ private ButtonType mType;
+ private int mIndex;
+
+ internal LaunchpadButton(LaunchpadDevice launchpadDevice, ButtonType type, int index)
+ {
+ mLaunchpadDevice = launchpadDevice;
+ mType = type;
+ mIndex = index;
+ }
+
+ public void TurnOnLight()
+ {
+ SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+ }
+
+ public void TurnOffLight()
+ {
+ SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+ }
+
+ public void SetBrightness(ButtonBrightness red, ButtonBrightness green)
+ {
+ if (mRedBrightness == red && mGreenBrightness == green)
+ return;
+
+ mRedBrightness = red;
+ mGreenBrightness = green;
+
+ int vel = ((int)mGreenBrightness << 4) | (int)mRedBrightness;
+
+ if (!mLaunchpadDevice.DoubleBuffered)
+ vel |= 12;
+
+ SetLED(vel);
+ }
+
+ private void SetLED(int value)
+ {
+ if (mType == ButtonType.Toolbar)
+ mLaunchpadDevice.OutputDevice.SendControlChange(Channel.Channel1, (Control)mIndex, value);
+ else
+ mLaunchpadDevice.OutputDevice.SendNoteOn(Channel.Channel1, (Pitch)mIndex, value);
+ }
+
+ public ButtonBrightness RedBrightness
+ {
+ get { return mRedBrightness; }
+ internal set { mRedBrightness = value; }
+ }
+
+ public ButtonBrightness GreenBrightness
+ {
+ get { return mGreenBrightness; }
+ internal set { mGreenBrightness = value; }
+ }
+
+ public ButtonPressState State
+ {
+ get { return mState; }
+ internal set { mState = value; }
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.Launchpad/LaunchpadDevice.cs b/launchpad-master/IntelOrca.Launchpad/LaunchpadDevice.cs
new file mode 100644
index 0000000..65d6ae9
--- /dev/null
+++ b/launchpad-master/IntelOrca.Launchpad/LaunchpadDevice.cs
@@ -0,0 +1,181 @@
+using Midi;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace IntelOrca.Launchpad
+{
+ public enum ToolbarButton { Up, Down, Left, Right, Session, User1, User2, Mixer }
+ public enum SideButton { Volume, Pan, SoundA, SoundB, Stop, TrackOn, Solo, Arm }
+
+ public class LaunchpadDevice
+ {
+ private InputDevice mInputDevice;
+ private OutputDevice mOutputDevice;
+
+ private bool mDoubleBuffered;
+ private bool mDoubleBufferedState;
+
+ private readonly LaunchpadButton[] mToolbar = new LaunchpadButton[8];
+ private readonly LaunchpadButton[] mSide = new LaunchpadButton[8];
+ private readonly LaunchpadButton[,] mGrid = new LaunchpadButton[8, 8];
+
+ public event EventHandler ButtonPressed;
+
+ public LaunchpadDevice() : this(0) { }
+
+ public LaunchpadDevice(int index)
+ {
+ InitialiseButtons();
+
+ int i = 0;
+ mInputDevice = InputDevice.InstalledDevices.Where(x => x.Name.Contains("Launchpad")).
+ FirstOrDefault(x => i++ == index);
+ i = 0;
+ mOutputDevice = OutputDevice.InstalledDevices.Where(x => x.Name.Contains("Launchpad")).
+ FirstOrDefault(x => i++ == index);
+
+ if (mInputDevice == null)
+ throw new LaunchpadException("Unable to find input device.");
+ if (mOutputDevice == null)
+ throw new LaunchpadException("Unable to find output device.");
+
+ mInputDevice.Open();
+ mOutputDevice.Open();
+
+ mInputDevice.StartReceiving(new Clock(120));
+ mInputDevice.NoteOn += mInputDevice_NoteOn;
+ mInputDevice.ControlChange += mInputDevice_ControlChange;
+
+ Reset();
+ }
+
+
+ private void InitialiseButtons()
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ mToolbar[i] = new LaunchpadButton(this, ButtonType.Toolbar, 104 + i);
+ mSide[i] = new LaunchpadButton(this, ButtonType.Side, i * 16 + 8);
+ }
+
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ mGrid[x, y] = new LaunchpadButton(this, ButtonType.Grid, y * 16 + x);
+ }
+
+ private void StartDoubleBuffering()
+ {
+ mDoubleBuffered = true;
+ mDoubleBufferedState = false;
+ mOutputDevice.SendControlChange(Channel.Channel1, (Control)0, 32 | 16 | 1);
+ }
+
+ public void Refresh()
+ {
+ if (!mDoubleBufferedState)
+ mOutputDevice.SendControlChange(Channel.Channel1, (Control)0, 32 | 16 | 4);
+ else
+ mOutputDevice.SendControlChange(Channel.Channel1, (Control)0, 32 | 16 | 1);
+ mDoubleBufferedState = !mDoubleBufferedState;
+ }
+
+ private void EndDoubleBuffering()
+ {
+ mOutputDevice.SendControlChange(Channel.Channel1, (Control)0, 32 | 16);
+ mDoubleBuffered = false;
+ }
+
+ public void Reset()
+ {
+ mOutputDevice.SendControlChange(Channel.Channel1, (Control)0, 0);
+ Buttons.ToList().ForEach(x => x.RedBrightness = x.GreenBrightness = ButtonBrightness.Off);
+ }
+
+ private void mInputDevice_NoteOn(NoteOnMessage msg)
+ {
+ LaunchpadButton button = GetButton(msg.Pitch);
+ if (button == null)
+ return;
+
+ button.State = (ButtonPressState)msg.Velocity;
+
+ if (ButtonPressed != null && button.State == ButtonPressState.Down)
+ {
+ if ((int)msg.Pitch % 16 == 8)
+ ButtonPressed.Invoke(this, new ButtonPressEventArgs((SideButton)((int)msg.Pitch / 16)));
+ else
+ ButtonPressed.Invoke(this, new ButtonPressEventArgs((int)msg.Pitch % 16, (int)msg.Pitch / 16));
+ }
+ }
+
+ private void mInputDevice_ControlChange(ControlChangeMessage msg)
+ {
+ ToolbarButton toolbarButton = (ToolbarButton)((int)msg.Control - 104);
+
+ LaunchpadButton button = GetButton(toolbarButton);
+ if (button == null)
+ return;
+
+ button.State = (ButtonPressState)msg.Value;
+ if (ButtonPressed != null && button.State == ButtonPressState.Down)
+ {
+ ButtonPressed.Invoke(this, new ButtonPressEventArgs(toolbarButton));
+ }
+ }
+
+ public LaunchpadButton GetButton(ToolbarButton toolbarButton)
+ {
+ return mToolbar[(int)toolbarButton];
+ }
+
+ public LaunchpadButton GetButton(SideButton sideButton)
+ {
+ return mSide[(int)sideButton];
+ }
+
+ private LaunchpadButton GetButton(Pitch pitch)
+ {
+ int x = (int)pitch % 16;
+ int y = (int)pitch / 16;
+ if (x < 8 && y < 8)
+ return mGrid[x, y];
+ else if (x == 8 && y < 8)
+ return mSide[y];
+
+ return null;
+ }
+
+ public bool DoubleBuffered
+ {
+ get { return mDoubleBuffered; }
+ set
+ {
+ if (mDoubleBuffered)
+ EndDoubleBuffering();
+ else
+ StartDoubleBuffering();
+ }
+ }
+
+ public LaunchpadButton this[int x, int y]
+ {
+ get { return mGrid[x, y]; }
+ }
+
+ public IEnumerable Buttons
+ {
+ get
+ {
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ yield return mGrid[x, y];
+ }
+ }
+
+ internal OutputDevice OutputDevice
+ {
+ get { return mOutputDevice; }
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.Launchpad/LaunchpadException.cs b/launchpad-master/IntelOrca.Launchpad/LaunchpadException.cs
new file mode 100644
index 0000000..7ee6c4c
--- /dev/null
+++ b/launchpad-master/IntelOrca.Launchpad/LaunchpadException.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace IntelOrca.Launchpad
+{
+ public class LaunchpadException : Exception
+ {
+ public LaunchpadException() : base() { }
+ public LaunchpadException(string message) : base(message) { }
+ }
+}
diff --git a/launchpad-master/IntelOrca.Launchpad/Properties/AssemblyInfo.cs b/launchpad-master/IntelOrca.Launchpad/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..04fde0d
--- /dev/null
+++ b/launchpad-master/IntelOrca.Launchpad/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("IntelOrca.Launchpad")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("IntelOrca.Launchpad")]
+[assembly: AssemblyCopyright("Copyright © Ted John 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("02ec4a3e-47d6-4482-a424-0bde02acc866")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/launchpad-master/IntelOrca.Launchpad/packages.config b/launchpad-master/IntelOrca.Launchpad/packages.config
new file mode 100644
index 0000000..32a593b
--- /dev/null
+++ b/launchpad-master/IntelOrca.Launchpad/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/App.config b/launchpad-master/IntelOrca.LaunchpadTests/App.config
new file mode 100644
index 0000000..8e15646
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/Bulldog.cs b/launchpad-master/IntelOrca.LaunchpadTests/Bulldog.cs
new file mode 100644
index 0000000..e7c8b31
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/Bulldog.cs
@@ -0,0 +1,158 @@
+using IntelOrca.Launchpad;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Media;
+
+namespace IntelOrca.LaunchpadTests
+{
+ class Bulldog
+ {
+ private LaunchpadDevice mLaunchpadDevice;
+ private List mDogs = new List();
+ private Random mRandom = new Random();
+
+ private long mCurrentTicks = 0;
+ private long mNextDogTick = 2000;
+
+ private int mMisses, mHits;
+
+ public Bulldog(LaunchpadDevice device)
+ {
+ mLaunchpadDevice = device;
+ mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
+ }
+
+ private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e)
+ {
+ if (e.Type == ButtonType.Grid) {
+ var pressedDogs = mDogs.Where(d => (int)d.X == e.X && (int)d.Y == e.Y);
+ pressedDogs.ToList().ForEach(d => d.Killed = true);
+ if (pressedDogs.Count() > 0)
+ SystemSounds.Beep.Play();
+ }
+ }
+
+ public void Play()
+ {
+ long last_tick = Environment.TickCount;
+ long delay = 12;
+
+ while (true) {
+ if (Environment.TickCount - last_tick < delay)
+ continue;
+ mCurrentTicks += Environment.TickCount - last_tick;
+ last_tick = Environment.TickCount;
+
+ Update();
+ Draw();
+ }
+ }
+
+ private void Update()
+ {
+ mDogs.ForEach(d => d.Update());
+
+ var missedDogs = mDogs.Where(d => d.LeftGrid);
+ var hitDogs = mDogs.Where(d => d.Killed);
+
+ mMisses += missedDogs.Count();
+ mHits += hitDogs.Count();
+
+ mDogs.RemoveAll(d => d.LeftGrid || d.Killed);
+
+ if (mDogs.Count < 8) {
+ if (mCurrentTicks > mNextDogTick) {
+ mDogs.Add(GetNewDog());
+ mNextDogTick = mCurrentTicks + mRandom.Next(100, 1000);
+ }
+ }
+
+ Console.Clear();
+ Console.WriteLine("Misses: {0:0000}", mMisses);
+ Console.WriteLine("Hits: {0:0000}", mHits);
+ Console.WriteLine("Score: {0:0000}", (mHits * 10) - (mMisses * 5));
+ }
+
+ private void Draw()
+ {
+ ButtonBrightness[,] redgrid = new ButtonBrightness[8, 8];
+ ButtonBrightness[,] greengrid = new ButtonBrightness[8, 8];
+
+ mDogs.ForEach(d => {
+ if (!(d.X >= 0 && d.X < 8 && d.Y >= 0 && d.Y < 8))
+ return;
+
+ redgrid[(int)d.X, (int)d.Y] = ButtonBrightness.Full;
+ greengrid[(int)d.X, (int)d.Y] = ButtonBrightness.Full;
+ });
+
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ mLaunchpadDevice[x, y].SetBrightness(redgrid[x, y], greengrid[x, y]);
+ mLaunchpadDevice.Refresh();
+ }
+
+ private Dog GetNewDog()
+ {
+ Dog dog = new Dog();
+
+ if (mRandom.Next(2) == 0) {
+ // Row
+ dog.Y = mRandom.Next(8);
+ dog.VX = mRandom.NextDouble() / 5;
+ dog.X = 0;
+ if (mRandom.Next(2) == 0) {
+ dog.X = 7;
+ dog.VX *= -1;
+ }
+
+ } else {
+ // Column
+ dog.X = mRandom.Next(8);
+ dog.VY = mRandom.NextDouble() / 5;
+ dog.Y = 0;
+ if (mRandom.Next(2) == 0) {
+ dog.Y = 7;
+ dog.VY *= -1;
+ }
+ }
+
+ return dog;
+ }
+
+ class Dog
+ {
+ public Dog() { }
+
+ public void Update()
+ {
+ X += VX;
+ Y += VY;
+ }
+
+ public bool LeftGrid
+ {
+ get
+ {
+ if (X < 0 && VX <= 0)
+ return true;
+ if (Y < 0 && VY <= 0)
+ return true;
+ if (X >= 8 && VX >= 0)
+ return true;
+ if (Y >= 8 && VY >= 0)
+ return true;
+ return false;
+ }
+ }
+
+ public bool Killed { get; set; }
+ public int Colour { get; set; }
+ public double X { get; set; }
+ public double Y { get; set; }
+ public double VX { get; set; }
+ public double VY { get; set; }
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/GeometrischeTests.cs b/launchpad-master/IntelOrca.LaunchpadTests/GeometrischeTests.cs
new file mode 100644
index 0000000..00f8060
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/GeometrischeTests.cs
@@ -0,0 +1,1395 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using IntelOrca.Launchpad;
+
+namespace IntelOrca.LaunchpadTests
+{
+
+ class GeometrischeTests
+ {
+ private LaunchpadDevice mLaunchpadDevice;
+ private long mCurrentTicks = 0;
+
+ //Default speed is 4, valid speed frame is 1 - 9
+ private int speed = 4;
+ long delay;
+ private List availablePointGroups = new List();
+ private int activeGroup = -1;
+
+ private bool paused = false;
+ private bool gameEnd = false;
+
+ // Rects for centerbased Animation (only 4 max possible)
+ private Point[] Rect_center;
+ private Point[] Rect_inner;
+ private Point[] Rect_outer;
+ private Point[] Rect_edge;
+
+ // Lines for Horizontal based animation (8 Lines)
+ private Point[] Line_Top;
+ private Point[] Line_Upper;
+ private Point[] Line_UpperMid;
+ private Point[] Line_MidTop;
+ private Point[] Line_MidBot;
+ private Point[] Line_LowerMid;
+ private Point[] Line_Lower;
+ private Point[] Line_Bottom;
+
+ // Lines for Vertical based animation (8 Lines)
+ private Point[] Line_LeftEdge;
+ private Point[] Line_LeftOuter;
+ private Point[] Line_LeftInner;
+ private Point[] Line_MidLeft;
+ private Point[] Line_MidRight;
+ private Point[] Line_RightInner;
+ private Point[] Line_RightOuter;
+ private Point[] Line_RightEdge;
+
+ Random Randomizer;
+
+ //Specialty Groups
+ Point[] refreshGroup;
+ Point[] decayGroup;
+ int refreshIndexer;
+ int decayIndexer;
+ int raisingIndexer;
+ List currentActiveGroup ;
+ List currentRaisingActiveGroup = new List();
+
+
+ public enum animationColorMode { Green2Red, Red2Green, Green2Green, Red2Red };
+ animationColorMode currentMode = animationColorMode.Green2Green;
+
+ public enum animationStyle { CenteredIn, CenteredOut, HorizontalDown, HorizontalUp, VerticalRight, VerticalLeft, Noise, SmoothNoise, Matrix, WaveHorizontal, WaveVertical };
+ animationStyle currentStyle = animationStyle.VerticalRight;
+ public GeometrischeTests(LaunchpadDevice device)
+ {
+ mLaunchpadDevice = device;
+
+ //Add Buttonpress-Handler
+ mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
+
+ mLaunchpadDevice.GetButton(SideButton.Arm).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice.GetButton(SideButton.Solo).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+
+ mLaunchpadDevice.GetButton(SideButton.Volume).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ mLaunchpadDevice.GetButton(SideButton.Pan).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Medium);
+
+ mLaunchpadDevice.GetButton(SideButton.SoundA).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+ mLaunchpadDevice.GetButton(SideButton.SoundB).SetBrightness(ButtonBrightness.Low, ButtonBrightness.Low);
+
+ //Randomizer with always different Timestamp
+ Randomizer = new Random(Convert.ToInt32((new TimeSpan(DateTime.UtcNow.Ticks - new DateTime(2013, 06, 08).Ticks).TotalMinutes)));
+
+ Init();
+ }
+
+ private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e)
+ {
+ // If gridbutton was pressed
+ if (e.Type == ButtonType.Grid)
+ {
+
+ }
+
+ // If SNDA button is pressed -> Cycle to next Style
+ if (e.Type == ButtonType.Side)
+ {
+ if (e.SidebarButton == SideButton.SoundA)
+ {
+ Init();
+ }
+ }
+
+ // If SNDB button is pressed -> Cycle to next Colormode
+ if (e.Type == ButtonType.Side)
+ {
+ if (e.SidebarButton == SideButton.SoundB)
+ {
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ currentMode = animationColorMode.Green2Red;
+ break;
+ case animationColorMode.Red2Red:
+ currentMode = animationColorMode.Red2Green;
+ break;
+ case animationColorMode.Green2Red:
+ currentMode = animationColorMode.Red2Red;
+ break;
+ case animationColorMode.Red2Green:
+ currentMode = animationColorMode.Green2Green;
+ break;
+ }
+ }
+ }
+
+ // If Volume button is pressed -> accelerate animation
+ if (e.Type == ButtonType.Side)
+ {
+ if (e.SidebarButton == SideButton.Volume)
+ {
+ if (speed > 1)
+ {
+ speed--;
+ }
+ }
+ }
+
+ // If Pan button is pressed -> decelerate animation
+ if (e.Type == ButtonType.Side)
+ {
+ if (e.SidebarButton == SideButton.Pan)
+ {
+ if (speed < 9)
+ {
+ speed++;
+ }
+ }
+ }
+
+ // if Solobutton is pressed -> toggle pause animation
+ if (e.Type == ButtonType.Side)
+ {
+ if (e.SidebarButton == SideButton.Solo)
+ {
+ if (paused)
+ paused = false;
+ else
+ paused = true;
+ }
+ }
+
+ //if armbutton is pressed -> end the loop
+ if (e.Type == ButtonType.Side)
+ {
+ if (e.SidebarButton == SideButton.Arm)
+ {
+ mLaunchpadDevice.Reset();
+ gameEnd = true;
+ }
+ }
+
+ }
+
+ private void Init()
+ {
+
+ // Set the different styles and modes
+ switch (currentStyle)
+ {
+ case animationStyle.CenteredIn:
+ currentStyle = animationStyle.CenteredOut;
+ break;
+ case animationStyle.CenteredOut:
+ currentStyle = animationStyle.HorizontalDown;
+ break;
+ case animationStyle.HorizontalDown:
+ currentStyle = animationStyle.HorizontalUp;
+ break;
+ case animationStyle.HorizontalUp:
+ currentStyle = animationStyle.VerticalLeft;
+ break;
+ case animationStyle.Noise:
+ currentStyle = animationStyle.SmoothNoise;
+ break;
+ case animationStyle.VerticalLeft:
+ currentStyle = animationStyle.VerticalRight;
+ break;
+ case animationStyle.VerticalRight:
+ currentStyle = animationStyle.Noise;
+ break;
+ case animationStyle.WaveHorizontal:
+ break;
+ case animationStyle.WaveVertical:
+ break;
+ case animationStyle.SmoothNoise:
+ currentStyle = animationStyle.CenteredIn;
+ break;
+ case animationStyle.Matrix:
+ currentStyle = animationStyle.CenteredIn;
+ break;
+ }
+
+ //Reset Group indexer
+ activeGroup = 0;
+
+
+ #region CenteredIn/Out
+ // Fill valid Points of all rectangles
+ if (currentStyle == animationStyle.CenteredIn || currentStyle == animationStyle.CenteredOut)
+ {
+ Rect_center = null;
+ Rect_center = new Point[4];
+ Rect_center[0] = new Point(3, 3);
+ Rect_center[1] = new Point(3, 4);
+ Rect_center[2] = new Point(4, 3);
+ Rect_center[3] = new Point(4, 4);
+
+ Rect_inner = null;
+ Rect_inner = new Point[12];
+ Rect_inner[0] = new Point(2, 2);
+ Rect_inner[1] = new Point(3, 2);
+ Rect_inner[2] = new Point(4, 2);
+ Rect_inner[3] = new Point(5, 2);
+ Rect_inner[4] = new Point(2, 3);
+ Rect_inner[5] = new Point(5, 3);
+ Rect_inner[6] = new Point(2, 4);
+ Rect_inner[7] = new Point(5, 4);
+ Rect_inner[8] = new Point(2, 5);
+ Rect_inner[9] = new Point(3, 5);
+ Rect_inner[10] = new Point(4, 5);
+ Rect_inner[11] = new Point(5, 5);
+
+ Rect_outer = null;
+ Rect_outer = new Point[20];
+ Rect_outer[0] = new Point(1, 1);
+ Rect_outer[1] = new Point(1, 2);
+ Rect_outer[2] = new Point(1, 3);
+ Rect_outer[3] = new Point(1, 4);
+ Rect_outer[4] = new Point(1, 5);
+ Rect_outer[5] = new Point(1, 6);
+ Rect_outer[6] = new Point(2, 1);
+ Rect_outer[7] = new Point(2, 6);
+ Rect_outer[8] = new Point(3, 1);
+ Rect_outer[9] = new Point(3, 6);
+ Rect_outer[10] = new Point(4, 1);
+ Rect_outer[11] = new Point(4, 6);
+ Rect_outer[12] = new Point(5, 1);
+ Rect_outer[13] = new Point(5, 6);
+ Rect_outer[14] = new Point(6, 1);
+ Rect_outer[15] = new Point(6, 2);
+ Rect_outer[16] = new Point(6, 3);
+ Rect_outer[17] = new Point(6, 4);
+ Rect_outer[18] = new Point(6, 5);
+ Rect_outer[19] = new Point(6, 6);
+
+ Rect_edge = null;
+ Rect_edge = new Point[28];
+ Rect_edge[0] = new Point(0, 0);
+ Rect_edge[1] = new Point(1, 0);
+ Rect_edge[2] = new Point(2, 0);
+ Rect_edge[3] = new Point(3, 0);
+ Rect_edge[4] = new Point(4, 0);
+ Rect_edge[5] = new Point(5, 0);
+ Rect_edge[6] = new Point(6, 0);
+ Rect_edge[7] = new Point(7, 0);
+ Rect_edge[8] = new Point(0, 1);
+ Rect_edge[9] = new Point(7, 1);
+ Rect_edge[10] = new Point(0, 2);
+ Rect_edge[11] = new Point(7, 2);
+ Rect_edge[12] = new Point(0, 3);
+ Rect_edge[13] = new Point(7, 3);
+ Rect_edge[14] = new Point(0, 4);
+ Rect_edge[15] = new Point(7, 4);
+ Rect_edge[16] = new Point(0, 5);
+ Rect_edge[17] = new Point(7, 5);
+ Rect_edge[18] = new Point(0, 6);
+ Rect_edge[19] = new Point(7, 6);
+ Rect_edge[20] = new Point(0, 7);
+ Rect_edge[21] = new Point(1, 7);
+ Rect_edge[22] = new Point(2, 7);
+ Rect_edge[23] = new Point(3, 7);
+ Rect_edge[24] = new Point(4, 7);
+ Rect_edge[25] = new Point(5, 7);
+ Rect_edge[26] = new Point(6, 7);
+ Rect_edge[27] = new Point(7, 7);
+
+ // Clear all remaining groups to prevent overload of unassagned point groups
+ availablePointGroups.Clear();
+ if (currentStyle == animationStyle.CenteredOut)
+ {
+
+ availablePointGroups.Add(Rect_center);
+ availablePointGroups.Add(Rect_inner);
+ availablePointGroups.Add(Rect_outer);
+ availablePointGroups.Add(Rect_edge);
+ }
+ else
+ {
+ availablePointGroups.Add(Rect_edge);
+ availablePointGroups.Add(Rect_outer);
+ availablePointGroups.Add(Rect_inner);
+ availablePointGroups.Add(Rect_center);
+ }
+ }
+ #endregion
+
+ #region Horizontal Up/Down
+ // Fill valid Points of all rectangles
+ if (currentStyle == animationStyle.HorizontalUp || currentStyle == animationStyle.HorizontalDown)
+ {
+
+ Line_Top = null;
+ Line_Top = new Point[8];
+ Line_Top[0] = new Point(0, 0);
+ Line_Top[1] = new Point(1, 0);
+ Line_Top[2] = new Point(2, 0);
+ Line_Top[3] = new Point(3, 0);
+ Line_Top[4] = new Point(4, 0);
+ Line_Top[5] = new Point(5, 0);
+ Line_Top[6] = new Point(6, 0);
+ Line_Top[7] = new Point(7, 0);
+
+ Line_Upper = null;
+ Line_Upper = new Point[8];
+ Line_Upper[0] = new Point(0, 1);
+ Line_Upper[1] = new Point(1, 1);
+ Line_Upper[2] = new Point(2, 1);
+ Line_Upper[3] = new Point(3, 1);
+ Line_Upper[4] = new Point(4, 1);
+ Line_Upper[5] = new Point(5, 1);
+ Line_Upper[6] = new Point(6, 1);
+ Line_Upper[7] = new Point(7, 1);
+
+
+ Line_UpperMid = null;
+ Line_UpperMid = new Point[8];
+ Line_UpperMid[0] = new Point(0, 2);
+ Line_UpperMid[1] = new Point(1, 2);
+ Line_UpperMid[2] = new Point(2, 2);
+ Line_UpperMid[3] = new Point(3, 2);
+ Line_UpperMid[4] = new Point(4, 2);
+ Line_UpperMid[5] = new Point(5, 2);
+ Line_UpperMid[6] = new Point(6, 2);
+ Line_UpperMid[7] = new Point(7, 2);
+
+
+ Line_MidTop = null;
+ Line_MidTop = new Point[8];
+ Line_MidTop[0] = new Point(0, 3);
+ Line_MidTop[1] = new Point(1, 3);
+ Line_MidTop[2] = new Point(2, 3);
+ Line_MidTop[3] = new Point(3, 3);
+ Line_MidTop[4] = new Point(4, 3);
+ Line_MidTop[5] = new Point(5, 3);
+ Line_MidTop[6] = new Point(6, 3);
+ Line_MidTop[7] = new Point(7, 3);
+
+ Line_MidBot = null;
+ Line_MidBot = new Point[8];
+ Line_MidBot[0] = new Point(0, 4);
+ Line_MidBot[1] = new Point(1, 4);
+ Line_MidBot[2] = new Point(2, 4);
+ Line_MidBot[3] = new Point(3, 4);
+ Line_MidBot[4] = new Point(4, 4);
+ Line_MidBot[5] = new Point(5, 4);
+ Line_MidBot[6] = new Point(6, 4);
+ Line_MidBot[7] = new Point(7, 4);
+
+ Line_LowerMid = null;
+ Line_LowerMid = new Point[8];
+ Line_LowerMid[0] = new Point(0, 5);
+ Line_LowerMid[1] = new Point(1, 5);
+ Line_LowerMid[2] = new Point(2, 5);
+ Line_LowerMid[3] = new Point(3, 5);
+ Line_LowerMid[4] = new Point(4, 5);
+ Line_LowerMid[5] = new Point(5, 5);
+ Line_LowerMid[6] = new Point(6, 5);
+ Line_LowerMid[7] = new Point(7, 5);
+
+ Line_Lower = null;
+ Line_Lower = new Point[8];
+ Line_Lower[0] = new Point(0, 6);
+ Line_Lower[1] = new Point(1, 6);
+ Line_Lower[2] = new Point(2, 6);
+ Line_Lower[3] = new Point(3, 6);
+ Line_Lower[4] = new Point(4, 6);
+ Line_Lower[5] = new Point(5, 6);
+ Line_Lower[6] = new Point(6, 6);
+ Line_Lower[7] = new Point(7, 6);
+
+ Line_Bottom = null;
+ Line_Bottom = new Point[8];
+ Line_Bottom[0] = new Point(0, 7);
+ Line_Bottom[1] = new Point(1, 7);
+ Line_Bottom[2] = new Point(2, 7);
+ Line_Bottom[3] = new Point(3, 7);
+ Line_Bottom[4] = new Point(4, 7);
+ Line_Bottom[5] = new Point(5, 7);
+ Line_Bottom[6] = new Point(6, 7);
+ Line_Bottom[7] = new Point(7, 7);
+
+
+ // Clear all remaining groups to prevent overload of unassagned point groups
+ availablePointGroups.Clear();
+ if (currentStyle == animationStyle.HorizontalDown)
+ {
+
+ availablePointGroups.Add(Line_Top);
+ availablePointGroups.Add(Line_Upper);
+ availablePointGroups.Add(Line_UpperMid);
+ availablePointGroups.Add(Line_MidTop);
+ availablePointGroups.Add(Line_MidBot);
+ availablePointGroups.Add(Line_LowerMid);
+ availablePointGroups.Add(Line_Lower);
+ availablePointGroups.Add(Line_Bottom);
+
+ }
+ else
+ {
+ availablePointGroups.Add(Line_Bottom);
+ availablePointGroups.Add(Line_Lower);
+ availablePointGroups.Add(Line_LowerMid);
+ availablePointGroups.Add(Line_MidBot);
+ availablePointGroups.Add(Line_MidTop);
+ availablePointGroups.Add(Line_UpperMid);
+ availablePointGroups.Add(Line_Upper);
+ availablePointGroups.Add(Line_Top);
+ }
+ }
+ #endregion
+
+ #region Vertical Left/Right
+ if (currentStyle == animationStyle.HorizontalUp || currentStyle == animationStyle.HorizontalDown)
+ {
+
+
+ Line_LeftEdge = null;
+ Line_LeftEdge = new Point[8];
+ Line_LeftEdge[0] = new Point(0, 0);
+ Line_LeftEdge[1] = new Point(0, 1);
+ Line_LeftEdge[2] = new Point(0, 2);
+ Line_LeftEdge[3] = new Point(0, 3);
+ Line_LeftEdge[4] = new Point(0, 4);
+ Line_LeftEdge[5] = new Point(0, 5);
+ Line_LeftEdge[6] = new Point(0, 6);
+ Line_LeftEdge[7] = new Point(0, 7);
+
+ Line_LeftOuter = null;
+ Line_LeftOuter = new Point[8];
+ Line_LeftOuter[0] = new Point(1, 0);
+ Line_LeftOuter[1] = new Point(1, 1);
+ Line_LeftOuter[2] = new Point(1, 2);
+ Line_LeftOuter[3] = new Point(1, 3);
+ Line_LeftOuter[4] = new Point(1, 4);
+ Line_LeftOuter[5] = new Point(1, 5);
+ Line_LeftOuter[6] = new Point(1, 6);
+ Line_LeftOuter[7] = new Point(1, 7);
+
+
+ Line_LeftInner = null;
+ Line_LeftInner = new Point[8];
+ Line_LeftInner[0] = new Point(2, 0);
+ Line_LeftInner[1] = new Point(2, 1);
+ Line_LeftInner[2] = new Point(2, 2);
+ Line_LeftInner[3] = new Point(2, 3);
+ Line_LeftInner[4] = new Point(2, 4);
+ Line_LeftInner[5] = new Point(2, 5);
+ Line_LeftInner[6] = new Point(2, 6);
+ Line_LeftInner[7] = new Point(2, 7);
+
+
+ Line_MidLeft = null;
+ Line_MidLeft = new Point[8];
+ Line_MidLeft[0] = new Point(3, 0);
+ Line_MidLeft[1] = new Point(3, 1);
+ Line_MidLeft[2] = new Point(3, 2);
+ Line_MidLeft[3] = new Point(3, 3);
+ Line_MidLeft[4] = new Point(3, 4);
+ Line_MidLeft[5] = new Point(3, 5);
+ Line_MidLeft[6] = new Point(3, 6);
+ Line_MidLeft[7] = new Point(3, 7);
+
+ Line_MidRight = null;
+ Line_MidRight = new Point[8];
+ Line_MidRight[0] = new Point(4, 0);
+ Line_MidRight[1] = new Point(4, 1);
+ Line_MidRight[2] = new Point(4, 2);
+ Line_MidRight[3] = new Point(4, 3);
+ Line_MidRight[4] = new Point(4, 4);
+ Line_MidRight[5] = new Point(4, 5);
+ Line_MidRight[6] = new Point(4, 6);
+ Line_MidRight[7] = new Point(4, 7);
+
+ Line_RightInner = null;
+ Line_RightInner = new Point[8];
+ Line_RightInner[0] = new Point(5, 0);
+ Line_RightInner[1] = new Point(5, 1);
+ Line_RightInner[2] = new Point(5, 2);
+ Line_RightInner[3] = new Point(5, 3);
+ Line_RightInner[4] = new Point(5, 4);
+ Line_RightInner[5] = new Point(5, 5);
+ Line_RightInner[6] = new Point(5, 6);
+ Line_RightInner[7] = new Point(5, 7);
+
+ Line_RightOuter = null;
+ Line_RightOuter = new Point[8];
+ Line_RightOuter[0] = new Point(6, 0);
+ Line_RightOuter[1] = new Point(6, 1);
+ Line_RightOuter[2] = new Point(6, 2);
+ Line_RightOuter[3] = new Point(6, 3);
+ Line_RightOuter[4] = new Point(6, 4);
+ Line_RightOuter[5] = new Point(6, 5);
+ Line_RightOuter[6] = new Point(6, 6);
+ Line_RightOuter[7] = new Point(6, 7);
+
+ Line_RightEdge = null;
+ Line_RightEdge = new Point[8];
+ Line_RightEdge[0] = new Point(7, 0);
+ Line_RightEdge[1] = new Point(7, 1);
+ Line_RightEdge[2] = new Point(7, 2);
+ Line_RightEdge[3] = new Point(7, 3);
+ Line_RightEdge[4] = new Point(7, 4);
+ Line_RightEdge[5] = new Point(7, 5);
+ Line_RightEdge[6] = new Point(7, 6);
+ Line_RightEdge[7] = new Point(7, 7);
+
+
+ // Clear all remaining groups to prevent overload of unassagned point groups
+ availablePointGroups.Clear();
+ if (currentStyle == animationStyle.VerticalRight)
+ {
+
+ availablePointGroups.Add(Line_LeftEdge);
+ availablePointGroups.Add(Line_LeftOuter);
+ availablePointGroups.Add(Line_LeftInner);
+ availablePointGroups.Add(Line_MidLeft);
+ availablePointGroups.Add(Line_MidRight);
+ availablePointGroups.Add(Line_RightInner);
+ availablePointGroups.Add(Line_RightOuter);
+ availablePointGroups.Add(Line_RightEdge);
+
+ }
+ else
+ {
+ availablePointGroups.Add(Line_RightEdge);
+ availablePointGroups.Add(Line_RightOuter);
+ availablePointGroups.Add(Line_RightInner);
+ availablePointGroups.Add(Line_MidRight);
+ availablePointGroups.Add(Line_MidLeft);
+ availablePointGroups.Add(Line_LeftInner);
+ availablePointGroups.Add(Line_LeftOuter);
+ availablePointGroups.Add(Line_LeftEdge);
+ }
+ }
+ #endregion
+ }
+
+ public void Run()
+ {
+ // Control of internal ticks (6*12 Frames are skipped to simulate a propper time pass)
+ long last_tick = Environment.TickCount;
+
+
+ // GameLoop
+ while (true && !gameEnd)
+ {
+ delay = 24 * speed;
+ if (Environment.TickCount - last_tick < delay)
+ continue;
+ mCurrentTicks += Environment.TickCount - last_tick;
+ last_tick = Environment.TickCount;
+
+ // Possibility to freeze the animation)
+ if (!paused)
+ {
+ // Update of all rect-colors
+ Update();
+ // redraw the new information on the board
+ Draw();
+ }
+
+ }
+ }
+ private void Update()
+ {
+
+ //Rotate to next group of points (restart at first at the end)
+ // potential inserting point of Rebounce cycling (start2end -> end2start instead of start2end->start2end)
+ if (activeGroup >= availablePointGroups.Count() - 1)
+ {
+ activeGroup = 0;
+ }
+ else
+ {
+ activeGroup++;
+ }
+
+ // only refresh active rect -> other ones "decay into next phase"
+ switch (currentStyle)
+ {
+ #region CenteredIn
+ case animationStyle.CenteredIn:
+ switch (activeGroup)
+ {
+ case 0:
+ decayGroupColors(Rect_center);
+ decayGroupColors(Rect_inner);
+ decayGroupColors(Rect_outer);
+ refreshGroupColors(Rect_edge);
+ break;
+ case 1:
+ decayGroupColors(Rect_center);
+ decayGroupColors(Rect_inner);
+ refreshGroupColors(Rect_outer);
+ decayGroupColors(Rect_edge);
+ break;
+ case 2:
+ decayGroupColors(Rect_center);
+ refreshGroupColors(Rect_inner);
+ decayGroupColors(Rect_outer);
+ decayGroupColors(Rect_edge);
+ break;
+ case 3:
+ refreshGroupColors(Rect_center);
+ decayGroupColors(Rect_inner);
+ decayGroupColors(Rect_outer);
+ decayGroupColors(Rect_edge);
+ break;
+
+ }
+
+ break;
+ #endregion
+ #region CenteredOut
+ case animationStyle.CenteredOut:
+ switch (activeGroup)
+ {
+ case 0:
+ refreshGroupColors(Rect_center);
+ decayGroupColors(Rect_inner);
+ decayGroupColors(Rect_outer);
+ decayGroupColors(Rect_edge);
+ break;
+ case 1:
+ decayGroupColors(Rect_center);
+ refreshGroupColors(Rect_inner);
+ decayGroupColors(Rect_outer);
+ decayGroupColors(Rect_edge);
+ break;
+ case 2:
+ decayGroupColors(Rect_center);
+ decayGroupColors(Rect_inner);
+ refreshGroupColors(Rect_outer);
+ decayGroupColors(Rect_edge);
+ break;
+ case 3:
+ decayGroupColors(Rect_center);
+ decayGroupColors(Rect_inner);
+ decayGroupColors(Rect_outer);
+ refreshGroupColors(Rect_edge);
+ break;
+
+ }
+ break;
+ #endregion
+ #region HorizontalDown
+ case animationStyle.HorizontalDown:
+ switch (activeGroup)
+ {
+ case 0:
+ refreshGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 1:
+ decayGroupColors(Line_Top);
+ refreshGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 2:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ refreshGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 3:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ refreshGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 4:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ refreshGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 5:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ refreshGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 6:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ refreshGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 7:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ refreshGroupColors(Line_Bottom);
+ break;
+
+ }
+ break;
+ #endregion
+ #region HorizontalUp
+ case animationStyle.HorizontalUp:
+ switch (activeGroup)
+ {
+ case 0:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ refreshGroupColors(Line_Bottom);
+ break;
+ case 1:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ refreshGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 2:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ refreshGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 3:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ refreshGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 4:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ refreshGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 5:
+ decayGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ refreshGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 6:
+ decayGroupColors(Line_Top);
+ refreshGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+ case 7:
+ refreshGroupColors(Line_Top);
+ decayGroupColors(Line_Upper);
+ decayGroupColors(Line_UpperMid);
+ decayGroupColors(Line_MidTop);
+ decayGroupColors(Line_MidBot);
+ decayGroupColors(Line_LowerMid);
+ decayGroupColors(Line_Lower);
+ decayGroupColors(Line_Bottom);
+ break;
+
+ }
+ break;
+ #endregion
+ #region Noise
+ case animationStyle.Noise:
+ //Pick certain amount of cells randomly and decay the rest
+ currentActiveGroup = new List();
+
+ while (currentActiveGroup.Count() < 8)
+ {
+ //create new Random point
+ Point TempPoint = new Point(Randomizer.Next(0, 8), Randomizer.Next(0, 8));
+
+ //check if new Point is allready in the current group
+ if (currentActiveGroup.Contains(TempPoint))
+ {
+ continue;
+ }
+ else
+ {
+ //if its not in the activeGroup it must be added
+ currentActiveGroup.Add(TempPoint);
+ }
+ }
+
+ Point[] refreshGroup = new Point[8];
+ int refreshIndexer = 0;
+
+ Point[] decayGroup = new Point[56];
+ int decayIndexer = 0;
+
+ //When the new group is picked, they shall be refreshed while the rest decays
+ for (int yPos = 0; yPos < 8; yPos++)
+ {
+ for (int xPos = 0; xPos < 8; xPos++)
+ {
+ Point TempPoint = new Point(xPos, yPos);
+ if (currentActiveGroup.Contains(TempPoint))
+ {
+ refreshGroup[refreshIndexer++] = new Point(TempPoint.X, TempPoint.Y);
+ }
+ else
+ {
+ decayGroup[decayIndexer++] = new Point(TempPoint.X, TempPoint.Y);
+ }
+ }
+ }
+
+ //after groups are sorted update their lightinformation
+ refreshGroupColors(refreshGroup);
+ decayGroupColors(decayGroup);
+
+ break;
+ #endregion
+ #region SmoothNoise
+ case animationStyle.SmoothNoise:
+ //Pick certain amount of cells randomly from the decaying group
+
+ while (currentRaisingActiveGroup.Count() < 32)
+ {
+ //create new Random point
+ Point TempPoint = new Point(Randomizer.Next(0, 8), Randomizer.Next(0, 8));
+
+ //check if new Point is allready in the current group
+ if (currentRaisingActiveGroup.Contains(TempPoint))
+ {
+ continue;
+ }
+ else
+ {
+ //if its not in the activeGroup it must be added
+ currentRaisingActiveGroup.Add(TempPoint);
+ }
+ }
+
+ //check if maxed ListEntries need to be put to decay again
+ List RemoveList = new List();
+ foreach (Point P in currentRaisingActiveGroup)
+ {
+ if (checkIfMaxedPoint(P))
+ {
+ RemoveList.Add(P);
+ }
+ }
+
+ foreach (Point P in RemoveList)
+ {
+ currentRaisingActiveGroup.Remove(P);
+ }
+
+ //technicly no Tiles are directly refreshed-> all will first be set to increase slowly
+ refreshGroup = new Point[currentRaisingActiveGroup.Count()];
+ refreshIndexer = 0;
+
+ //An Point not in the List of RaisingPoints will decay
+ decayGroup = new Point[64 - currentRaisingActiveGroup.Count()];
+ decayIndexer = 0;
+
+ //When the new group is picked, they shall be refreshed while the rest decays
+ for (int yPos = 0; yPos < 8; yPos++)
+ {
+ for (int xPos = 0; xPos < 8; xPos++)
+ {
+ Point TempPoint = new Point(xPos, yPos);
+ if (currentRaisingActiveGroup.Contains(TempPoint))
+ {
+ refreshGroup[refreshIndexer++] = new Point(TempPoint.X, TempPoint.Y);
+ }
+ else
+ {
+ decayGroup[decayIndexer++] = new Point(TempPoint.X, TempPoint.Y);
+ }
+ }
+ }
+
+ //after groups are sorted update their lightinformation
+ increaseGroupColors(refreshGroup);
+ decayGroupColors(decayGroup);
+
+
+ break;
+ #endregion
+ #region VerticalLeft
+ case animationStyle.VerticalLeft:
+ switch (activeGroup)
+ {
+ case 0:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ refreshGroupColors(Line_RightEdge);
+ break;
+ case 1:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ refreshGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 2:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ refreshGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 3:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ refreshGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 4:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ refreshGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 5:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ refreshGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 6:
+ decayGroupColors(Line_LeftEdge);
+ refreshGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 7:
+ refreshGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ }
+ break;
+ #endregion
+ #region VerticalRight
+ case animationStyle.VerticalRight:
+ switch (activeGroup)
+ {
+ case 0:
+ refreshGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 1:
+ decayGroupColors(Line_LeftEdge);
+ refreshGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 2:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ refreshGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 3:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ refreshGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 4:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ refreshGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 5:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ refreshGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 6:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ refreshGroupColors(Line_RightOuter);
+ decayGroupColors(Line_RightEdge);
+ break;
+ case 7:
+ decayGroupColors(Line_LeftEdge);
+ decayGroupColors(Line_LeftOuter);
+ decayGroupColors(Line_LeftInner);
+ decayGroupColors(Line_MidLeft);
+ decayGroupColors(Line_MidRight);
+ decayGroupColors(Line_RightInner);
+ decayGroupColors(Line_RightOuter);
+ refreshGroupColors(Line_RightEdge);
+ break;
+ }
+ break;
+ #endregion
+ case animationStyle.WaveHorizontal:
+ break;
+ case animationStyle.WaveVertical:
+ break;
+ }
+
+ }
+
+
+ private bool checkIfMaxedPoint(Point p)
+ {
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ if (mLaunchpadDevice[p.X, p.Y].GreenBrightness == ButtonBrightness.Full)
+ return true;
+ else
+ return false;
+ case animationColorMode.Green2Red:
+ if (mLaunchpadDevice[p.X, p.Y].GreenBrightness == ButtonBrightness.Full)
+ return true;
+ else
+ return false;
+ case animationColorMode.Red2Red:
+ if (mLaunchpadDevice[p.X, p.Y].RedBrightness == ButtonBrightness.Full)
+ return true;
+ else
+ return false;
+ case animationColorMode.Red2Green:
+ if (mLaunchpadDevice[p.X, p.Y].RedBrightness == ButtonBrightness.Full)
+ return true;
+ else
+ return false;
+ default:
+ return false;
+
+ }
+
+ }
+ private void refreshGroupColors(Point[] currentGroup)
+ {
+ //Depending on Colormode refresh the Brightness of that button group
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ }
+ break;
+ case animationColorMode.Green2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ }
+ break;
+ case animationColorMode.Red2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ }
+ break;
+ case animationColorMode.Red2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ }
+ break;
+ }
+
+ }
+
+ private void increaseGroupColors(Point[] currentGroup)
+ {
+ // Depending on colormode decay
+
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (mLaunchpadDevice[Tile.X, Tile.Y].GreenBrightness)
+ {
+ case ButtonBrightness.Off:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Medium:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ case ButtonBrightness.Low:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Medium);
+ break;
+
+ }
+ }
+ break;
+ case animationColorMode.Green2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (mLaunchpadDevice[Tile.X, Tile.Y].GreenBrightness)
+ {
+ case ButtonBrightness.Off:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Medium, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Medium:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ case ButtonBrightness.Low:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Low, ButtonBrightness.Medium);
+ break;
+
+ }
+ }
+ break;
+ case animationColorMode.Red2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (mLaunchpadDevice[Tile.X, Tile.Y].RedBrightness)
+ {
+ case ButtonBrightness.Off:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Low, ButtonBrightness.Medium);
+ break;
+ case ButtonBrightness.Medium:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Low:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Medium, ButtonBrightness.Low);
+ break;
+
+ }
+
+
+ }
+ break;
+ case animationColorMode.Red2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (mLaunchpadDevice[Tile.X, Tile.Y].RedBrightness)
+ {
+ case ButtonBrightness.Off:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Low, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Medium:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Low:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Medium, ButtonBrightness.Off);
+ break;
+
+ }
+
+ }
+ break;
+ }
+ }
+
+ private void decayGroupColors(Point[] currentGroup)
+ {
+ // Depending on colormode decay
+
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (mLaunchpadDevice[Tile.X, Tile.Y].GreenBrightness)
+ {
+ case ButtonBrightness.Full:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Medium);
+ break;
+ case ButtonBrightness.Medium:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Low:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+ break;
+
+ }
+ }
+ break;
+ case animationColorMode.Green2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (mLaunchpadDevice[Tile.X, Tile.Y].GreenBrightness)
+ {
+ case ButtonBrightness.Full:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Low, ButtonBrightness.Medium);
+ break;
+ case ButtonBrightness.Medium:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Medium, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Low:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+
+ }
+ }
+ break;
+ case animationColorMode.Red2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (mLaunchpadDevice[Tile.X, Tile.Y].RedBrightness)
+ {
+ case ButtonBrightness.Full:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Medium, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Medium:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Low, ButtonBrightness.Medium);
+ break;
+ case ButtonBrightness.Low:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+
+ }
+
+
+ }
+ break;
+ case animationColorMode.Red2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (mLaunchpadDevice[Tile.X, Tile.Y].RedBrightness)
+ {
+ case ButtonBrightness.Full:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Medium, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Medium:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Low, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Low:
+ mLaunchpadDevice[Tile.X, Tile.Y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+ break;
+
+ }
+
+ }
+ break;
+ }
+ }
+ private void Draw()
+ {
+
+ // Refresh devices light information
+ mLaunchpadDevice.Refresh();
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/IntelOrca.LaunchpadTests.csproj b/launchpad-master/IntelOrca.LaunchpadTests/IntelOrca.LaunchpadTests.csproj
new file mode 100644
index 0000000..12a6d2a
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/IntelOrca.LaunchpadTests.csproj
@@ -0,0 +1,75 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {C2C7FD5A-D56C-4C74-91E3-2D9F5D92FCA3}
+ Exe
+ Properties
+ IntelOrca.LaunchpadTests
+ IntelOrca.LaunchpadTests
+ v4.5
+ 512
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\midi-dot-net.1.1.0\lib\net35\Midi.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {fcf77754-c985-4f3d-be0b-e14011c5dc5b}
+ IntelOrca.Launchpad
+
+
+
+
+ PreserveNewest
+
+
+
+
+
\ No newline at end of file
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/PWGenerator.cs b/launchpad-master/IntelOrca.LaunchpadTests/PWGenerator.cs
new file mode 100644
index 0000000..ce27511
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/PWGenerator.cs
@@ -0,0 +1,1261 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.IO;
+using IntelOrca.Launchpad;
+
+namespace IntelOrca.LaunchpadTests
+{
+ public struct virtualButton
+ {
+ public int PosX;
+ public int PosY;
+ public ButtonBrightness IntensityGreen;
+ public ButtonBrightness IntensityRed;
+ }
+
+ public class PWGenerator
+ {
+ private LaunchpadDevice mLaunchpadDevice;
+ private long mCurrentTicks = 0;
+ private bool appFrozen = false;
+ private bool appEnd = false;
+ private int screenSaverTimer = 0;
+ //Default speed is 4, valid speed frame is 1 - 9
+ private int speed = 4;
+ long delay;
+ virtualButton[,] virtualGrid = new virtualButton[8, 8];
+
+ Random NoiseRandomizer;
+ Random FieldValRandomizer;
+ //Default Seed
+ int Seed = 12345;
+ //Default Private Key
+ int privateKey = 54321;
+ Random CharValRandomizer;
+
+
+ List currentRaisingActiveGroup = new List();
+ int refreshIndexer;
+ int decayIndexer;
+ Point[] refreshGroup;
+ Point[] decayGroup;
+ Point ChosenPoint;
+ int[,] FieldValues;
+ Point currentTrailPoint;
+ Point TargetPoint;
+
+ bool isDigitalDevice = true;
+ bool screenSaverWasKilled = false;
+ bool setUpNewRound = true;
+
+ // Building a trail is 0 = inactive, 1 = initializing, 2 = in process
+ int buildingTrail = 0;
+ string currentPasswordChunk = "";
+ string finalPassword = "";
+ Queue ImageList;
+ private string processMode = "Horizontal_Green";
+
+ //Default Codepage
+ private string codePage = "65001 Unicode";
+ // codepageMode activates a certain codepage to be used as characters
+ private string characterSet = "CharsOnly";
+ // in combination with codepage gives the range of chars that are
+
+ private bool screensaverOn = false;
+
+ public enum animationColorMode { Green2Red, Red2Green, Green2Green, Red2Red };
+ animationColorMode currentMode = animationColorMode.Green2Green;
+
+ public enum animationStyle { CenteredIn, CenteredOut, HorizontalDown, HorizontalUp, VerticalRight, VerticalLeft, Noise, SmoothNoise, Matrix, WaveHorizontal, WaveVertical };
+ animationStyle currentStyle = animationStyle.VerticalRight;
+
+ public PWGenerator(LaunchpadDevice device)
+ {
+ if (device != null)
+ {
+ mLaunchpadDevice = device;
+ mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
+ mLaunchpadDevice.GetButton(SideButton.Arm).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice.GetButton(SideButton.Solo).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+ mLaunchpadDevice.GetButton(SideButton.TrackOn).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ isDigitalDevice = false;
+ }
+
+ //Randomizer with always different Timestamp
+ NoiseRandomizer = new Random(Convert.ToInt32((new TimeSpan(DateTime.UtcNow.Ticks - new DateTime(2013, 06, 08).Ticks).TotalMinutes)));
+ //Randomizer to always generate different chars from the current field value depending on the current chunk
+ CharValRandomizer = new Random(privateKey);
+ //Set field Values depending on given private Key
+ FieldValues = new int[8, 8];
+ fillFieldValues(Seed);
+
+ ImageList = new Queue();
+
+ }
+
+ public PWGenerator(LaunchpadDevice device, int Seed, int privateKey, string charSet = "Nur Buchstaben", string codePage = "65001 Unicode")
+ {
+ if (device != null)
+ {//if no launchpad is available use a virtual field logic
+ mLaunchpadDevice = device;
+ mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
+ mLaunchpadDevice.GetButton(SideButton.Arm).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice.GetButton(SideButton.Solo).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+ mLaunchpadDevice.GetButton(SideButton.TrackOn).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ isDigitalDevice = false;
+ }
+ else
+ {
+ mLaunchpadDevice = null;
+ fillVirtualGrid();
+ }
+
+ this.Seed = Seed;
+ this.privateKey = privateKey;
+ this.characterSet = charSet;
+ this.codePage = codePage;
+
+
+
+ //Randomizer with always different Timestamp
+ NoiseRandomizer = new Random(Convert.ToInt32((new TimeSpan(DateTime.UtcNow.Ticks - new DateTime(2013, 06, 08).Ticks).TotalMinutes)));
+ //Randomizer to always generate different chars from the current field value depending on the current chunk
+ CharValRandomizer = new Random(privateKey);
+ //Set field Values depending on given private Key
+ FieldValues = new int[8, 8];
+ fillFieldValues(Seed);
+
+ ImageList = new Queue();
+ }
+
+
+ private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e)
+ {
+
+
+ if (e.Type == ButtonType.Grid)
+ {
+ if (screensaverOn)
+ {
+ screensaverOn = false;
+ screenSaverTimer = 0;
+ screenSaverWasKilled = true;
+ speed = 2;
+
+ }
+ else
+ {
+ // to prevent multiinput buttonpress while trailing Proccess has no use
+ if (buildingTrail == 0 && !appFrozen)
+ {
+ mLaunchpadDevice[e.X, e.Y].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+ ChosenPoint.X = e.X;
+ ChosenPoint.Y = e.Y;
+ buildingTrail = 1;
+
+ createImageFromPoint(ChosenPoint);
+
+ }
+ //Reset Screensavertimer
+ screensaverOn = false;
+ screenSaverTimer = 0;
+ }
+ }
+
+ if (e.Type == ButtonType.Toolbar)
+ {
+ if (e.ToolbarButton == ToolbarButton.Session && buildingTrail == 0)
+ {
+ if (mLaunchpadDevice.GetButton(ToolbarButton.Session).RedBrightness == ButtonBrightness.Full)
+ {
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ //Enlight Targetpoints in corresponding Color
+ mLaunchpadDevice[3, 3].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice[3, 4].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice[4, 3].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice[4, 4].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ processMode = "Horizontal_Green";
+ currentMode = animationColorMode.Green2Green;
+ }
+ else
+ {
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ //Enlight Targetpoints in corresponding Color
+ mLaunchpadDevice[3, 3].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ mLaunchpadDevice[3, 4].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ mLaunchpadDevice[4, 3].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ mLaunchpadDevice[4, 4].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ processMode = "Vertical_Red";
+ currentMode = animationColorMode.Red2Red;
+ }
+ mLaunchpadDevice.Refresh();
+ }
+ }
+
+ if (e.Type == ButtonType.Side)
+ {
+ if (e.SidebarButton == SideButton.TrackOn)
+ {
+
+ mLaunchpadDevice.Reset();
+ appEnd = true;
+ }
+ }
+
+ if (e.Type == ButtonType.Side)
+ {
+ // Disable freezing the calculating process to prevent aborting a pathcalculation with a screensaver
+ if (e.SidebarButton == SideButton.Solo && buildingTrail == 0)
+ {
+ if (appFrozen)
+ appFrozen = false;
+ else
+ appFrozen = true;
+ }
+ }
+
+ if (e.Type == ButtonType.Side)
+ {
+ if (e.SidebarButton == SideButton.Arm)
+ {
+ clearAllFields();
+ finalPassword = "";
+ appEnd = true;
+ }
+ }
+
+
+ }
+
+ public void virtualButtonPress(string buttonType, int buttonX, int buttonY)
+ {
+ switch (buttonType)
+ {
+ case "Grid":
+ // to prevent multiinput buttonpress while trailing Proccess has no use
+ if (buildingTrail == 0 && !appFrozen)
+ {
+ virtualGrid[buttonX, buttonY].IntensityGreen = ButtonBrightness.Full;
+ virtualGrid[buttonX, buttonY].IntensityRed = ButtonBrightness.Full;
+ ChosenPoint.X = buttonX;
+ ChosenPoint.Y = buttonY;
+ buildingTrail = 1;
+
+ createImageFromPoint(ChosenPoint);
+
+ }
+ break;
+ case "Enter":
+ appEnd = true;
+ break;
+ case "ChangeProcessMode":
+ if (buildingTrail == 0)
+ {
+ if (processMode == "VerticalRed")
+ {
+ //If change to Horizontal green is imminent, change center field colors to red
+ virtualGrid[3, 3].IntensityGreen = ButtonBrightness.Off;
+ virtualGrid[3, 3].IntensityRed = ButtonBrightness.Full;
+ virtualGrid[3, 4].IntensityGreen = ButtonBrightness.Off;
+ virtualGrid[3, 4].IntensityRed = ButtonBrightness.Full;
+ virtualGrid[4, 3].IntensityGreen = ButtonBrightness.Off;
+ virtualGrid[4, 3].IntensityRed = ButtonBrightness.Full;
+ virtualGrid[4, 4].IntensityGreen = ButtonBrightness.Off;
+ virtualGrid[4, 4].IntensityRed = ButtonBrightness.Full;
+ processMode = "Horizontal_Green";
+ currentMode = animationColorMode.Green2Green;
+
+ }
+ else
+ {
+ virtualGrid[3, 3].IntensityGreen = ButtonBrightness.Full;
+ virtualGrid[3, 3].IntensityRed = ButtonBrightness.Off;
+ virtualGrid[3, 4].IntensityGreen = ButtonBrightness.Full;
+ virtualGrid[3, 4].IntensityRed = ButtonBrightness.Off;
+ virtualGrid[4, 3].IntensityGreen = ButtonBrightness.Full;
+ virtualGrid[4, 3].IntensityRed = ButtonBrightness.Off;
+ virtualGrid[4, 4].IntensityGreen = ButtonBrightness.Full;
+ virtualGrid[4, 4].IntensityRed = ButtonBrightness.Off;
+ processMode = "Vertical_Red";
+ currentMode = animationColorMode.Red2Red;
+ }
+
+ }
+
+
+ break;
+ case "Cancel":
+
+ finalPassword = "";
+ appEnd = true;
+
+ break;
+ }
+
+ }
+ public bool Run()
+ {
+ //Function for external operation (with device)
+ // controll over internal tick clock (6*12 Frames are skipped until next action to achieve a viewable result)
+ long last_tick = Environment.TickCount;
+
+
+ // main processing loop
+ while (true && !appEnd)
+ {
+ delay = 24 * speed;
+ if (Environment.TickCount - last_tick < delay)
+ continue;
+
+ screenSaverTimer++;
+
+
+ if (screenSaverWasKilled || setUpNewRound)
+ {
+ // Kill all screensaver lights
+ for (int xPos = 0; xPos < 8; xPos++)
+ {
+ for (int yPos = 0; yPos < 8; yPos++)
+ {
+ mLaunchpadDevice[xPos, yPos].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+ }
+ }
+ // Restore the regular lights
+ setUpNewEntry();
+ screenSaverWasKilled = false;
+ setUpNewRound = false;
+ }
+
+ if (screenSaverTimer >= 300)
+ {
+ screensaverOn = true;
+ speed = 6;
+ }
+ mCurrentTicks += Environment.TickCount - last_tick;
+ last_tick = Environment.TickCount;
+
+ // Basic update-routine with integrated "freeze" function
+ if (!appFrozen)
+ {
+ // Update aller Positionen
+ Update();
+ // Neu Zeichnen des Brettes
+ Draw();
+ }
+
+ }
+
+ if (finalPassword == "")
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ private void Update()
+ {
+ //TODO
+ // Methode zum setzen von virtuellem oder launchpad feld erstellen und hier integrieren
+
+
+ //Features to implement:
+ //- CodePages integrieren
+ //- Externes Inputdevice in eigenem Window integrieren
+ //- Prüfungen ob alle Konfig-Felder gefüllt sind bevor PW-Generierung gestartet wird
+ //- Prüfungen, ob alle Konfig-Felder legitime Inhalte haben -> Seed und Key müssen int sein
+ //- Scale der Icons dynamisch an Eingabemenge anpassen (Egal wie viele Buttons gedrückt werden Icons müssen immer in die Groupbox passen)
+ //- Mehrzeilen Finales Passwort muss bei mehr als 2 Stellen Scrollbar sein
+ // If screensaver is active display the noise light pattern
+ if (screensaverOn)
+ {
+ while (currentRaisingActiveGroup.Count() < 32)
+ {
+ //create new Random point
+ Point TempPoint = new Point(NoiseRandomizer.Next(0, 8), NoiseRandomizer.Next(0, 8));
+
+ //check if new Point is allready in the current group
+ if (currentRaisingActiveGroup.Contains(TempPoint))
+ {
+ continue;
+ }
+ else
+ {
+ //if its not in the activeGroup it must be added
+ currentRaisingActiveGroup.Add(TempPoint);
+ }
+ }
+
+ //check if maxed ListEntries need to be put to decay again
+ List RemoveList = new List();
+ foreach (Point P in currentRaisingActiveGroup)
+ {
+ if (checkIfMaxedPoint(P))
+ {
+ RemoveList.Add(P);
+ }
+ }
+
+ foreach (Point P in RemoveList)
+ {
+ currentRaisingActiveGroup.Remove(P);
+ }
+
+ //technicly no Tiles are directly refreshed-> all will first be set to increase slowly
+ refreshGroup = new Point[currentRaisingActiveGroup.Count()];
+ refreshIndexer = 0;
+
+ //An Point not in the List of RaisingPoints will decay
+ decayGroup = new Point[64 - currentRaisingActiveGroup.Count()];
+ decayIndexer = 0;
+
+ //When the new group is picked, they shall be refreshed while the rest decays
+ for (int yPos = 0; yPos < 8; yPos++)
+ {
+ for (int xPos = 0; xPos < 8; xPos++)
+ {
+ Point TempPoint = new Point(xPos, yPos);
+ if (currentRaisingActiveGroup.Contains(TempPoint))
+ {
+ refreshGroup[refreshIndexer++] = new Point(TempPoint.X, TempPoint.Y);
+ }
+ else
+ {
+ decayGroup[decayIndexer++] = new Point(TempPoint.X, TempPoint.Y);
+ }
+ }
+ }
+
+ //after groups are sorted update their lightinformation
+ increaseGroupColors(refreshGroup);
+ decayGroupColors(decayGroup);
+ }
+ else
+ {
+
+ //if a Trail needs to be build, don't set a new Target
+ if (buildingTrail == 1)
+ {
+ //Check to whitch of the middle ref fields it is closest to
+ switch (checkQuadrantOfPoint(ChosenPoint))
+ {
+ case "UpLeft":
+ TargetPoint.X = 3;
+ TargetPoint.Y = 3;
+ break;
+ case "UpRight":
+ TargetPoint.X = 4;
+ TargetPoint.Y = 3;
+ break;
+ case "DownLeft":
+ TargetPoint.X = 3;
+ TargetPoint.Y = 4;
+ break;
+ case "DownRight":
+ TargetPoint.X = 4;
+ TargetPoint.Y = 4;
+ break;
+ }
+
+ //Building a trail is initiated
+ currentTrailPoint = ChosenPoint;
+ buildingTrail = 2;
+ //Chosenpoint will also be picked for the pw-char
+ currentPasswordChunk = createPathChar("UTF-16");
+ }
+ else
+ {
+ if (buildingTrail == 2)
+ {
+ //before stepping on in the trail, old trailpoint needs to be turned off
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Green2Red", ButtonBrightness.Off, ButtonBrightness.Off);
+
+
+ //Depending on process mode horizontal or vertical path is prefered
+ switch (processMode)
+ {
+ case "Horizontal_Green":
+ if (currentTrailPoint.X != TargetPoint.X)
+ {//Currentpoint needs to make a step to the side depending on quarter it is in
+ switch (checkQuadrantOfPoint(ChosenPoint))
+ {
+ case "UpLeft":
+ case "DownLeft":
+ currentTrailPoint.X++;
+ break;
+ case "UpRight":
+ case "DownRight":
+ currentTrailPoint.X--;
+ break;
+ }
+ //Depending on ColorMode enlight current processed Button in corresponding color
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ case animationColorMode.Red2Red:
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Red", ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ }
+
+ //next char needs to be read from the field and calculated
+ currentPasswordChunk += createPathChar("UTF-16");
+ break;
+ }
+
+ if (currentTrailPoint.Y != TargetPoint.Y)
+ {// Currentpoint needs to make a step verticaly depending on quadrant
+ switch (checkQuadrantOfPoint(ChosenPoint))
+ {
+ case "UpLeft":
+ case "UpRight":
+ currentTrailPoint.Y++;
+ break;
+
+ case "DownLeft":
+ case "DownRight":
+ currentTrailPoint.Y--;
+ break;
+ }
+ //Depending on ColorMode enlight current processed Button in corresponding color
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ case animationColorMode.Red2Red:
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Red", ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ }
+ //next char needs to be read from the field and calculated
+ currentPasswordChunk += createPathChar("UTF-16");
+ break;
+ }
+ //if end of trail is reached, close trailbuilding process and initiate new field pic
+ if (currentTrailPoint.X == TargetPoint.X && currentTrailPoint.Y == TargetPoint.Y)
+ {
+ //Initialize all temporal Points
+ buildingTrail = 0;
+ setFieldColor(ChosenPoint.X, ChosenPoint.Y, "Green2Red", ButtonBrightness.Off, ButtonBrightness.Off);
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Green2Red", ButtonBrightness.Off, ButtonBrightness.Off);
+
+ currentTrailPoint.X = -1;
+ currentTrailPoint.Y = -1;
+
+ //Depending on ColorMode reset target button in corresponding color
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ setFieldColor(TargetPoint.X, TargetPoint.Y, "Green", ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ case animationColorMode.Red2Red:
+ setFieldColor(TargetPoint.X, TargetPoint.Y, "Red", ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ }
+ TargetPoint.X = -1;
+ TargetPoint.Y = -1;
+ ChosenPoint.X = -1;
+ ChosenPoint.Y = -1;
+
+ finalPassword += currentPasswordChunk;
+ Console.WriteLine(finalPassword);
+ }
+ break;
+ case "Vertical_Red":
+ if (currentTrailPoint.Y != TargetPoint.Y)
+ {// Currentpoint needs to make a step verticaly depending on quadrant
+ switch (checkQuadrantOfPoint(ChosenPoint))
+ {
+ case "UpLeft":
+ case "UpRight":
+ currentTrailPoint.Y++;
+ break;
+
+ case "DownLeft":
+ case "DownRight":
+ currentTrailPoint.Y--;
+ break;
+ }
+ //Depending on ColorMode enlight current processed Button in corresponding color
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ case animationColorMode.Red2Red:
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Red", ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ }
+ //next char needs to be read from the field and calculated
+ currentPasswordChunk += createPathChar("UTF-16");
+ break;
+ }
+
+ if (currentTrailPoint.X != TargetPoint.X)
+ {//Currentpoint needs to make a step to the side depending on quarter it is in
+ switch (checkQuadrantOfPoint(ChosenPoint))
+ {
+ case "UpLeft":
+ case "DownLeft":
+ currentTrailPoint.X++;
+ break;
+ case "UpRight":
+ case "DownRight":
+ currentTrailPoint.X--;
+ break;
+ }
+ //Depending on ColorMode enlight current processed Button in corresponding color
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ case animationColorMode.Red2Red:
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Red", ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice[currentTrailPoint.X, currentTrailPoint.Y].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ }
+ //next char needs to be read from the field and calculated
+ currentPasswordChunk += createPathChar("UTF-16");
+ break;
+ }
+
+ if (currentTrailPoint.X == TargetPoint.X && currentTrailPoint.Y == TargetPoint.Y)
+ {
+ //Initialize all temporal Points
+ buildingTrail = 0;
+ setFieldColor(ChosenPoint.X, ChosenPoint.Y, "Green2Red", ButtonBrightness.Off, ButtonBrightness.Off);
+ setFieldColor(currentTrailPoint.X, currentTrailPoint.Y, "Green2Red", ButtonBrightness.Off, ButtonBrightness.Off);
+
+ currentTrailPoint.X = -1;
+ currentTrailPoint.Y = -1;
+ //Depending on ColorMode reset target button in corresponding color
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ setFieldColor(TargetPoint.X, TargetPoint.Y, "Green", ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ case animationColorMode.Red2Red:
+ setFieldColor(TargetPoint.X, TargetPoint.Y, "Red", ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ }
+ TargetPoint.X = -1;
+ TargetPoint.Y = -1;
+ ChosenPoint.X = -1;
+ ChosenPoint.Y = -1;
+
+ finalPassword += currentPasswordChunk;
+ Console.WriteLine(finalPassword);
+ }
+ break;
+ }
+ }
+ }
+
+
+ }
+ }
+
+ private string checkQuadrantOfPoint(Point p)
+ {
+ // Check in whitch quater the point is in
+ if (p.X < 4 && p.Y < 4)
+ {
+ return "UpLeft";
+ }
+
+ if (p.X < 4 && p.Y > 3)
+ {
+ return "DownLeft";
+ }
+
+ if (p.X > 3 && p.Y < 4)
+ {
+ return "UpRight";
+ }
+
+ if (p.X > 3 && p.Y > 3)
+ {
+ return "DownRight";
+ }
+
+ return "Error";
+
+ }
+
+ private void setUpNewEntry()
+ {
+ //clear all current active buttons
+ clearAllFields();
+
+ //Set up Reference Fields
+ mLaunchpadDevice[3, 3].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice[4, 3].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice[3, 4].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice[4, 4].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+
+ //Set up ConfigButtons
+ mLaunchpadDevice.GetButton(SideButton.Arm).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice.GetButton(SideButton.Solo).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+ mLaunchpadDevice.GetButton(SideButton.TrackOn).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ }
+
+ private bool checkIfMaxedPoint(Point p)
+ {
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ if (getFieldColor(p.X, p.Y, "Green") == ButtonBrightness.Full)
+ return true;
+ else
+ return false;
+ case animationColorMode.Green2Red:
+ if (getFieldColor(p.X, p.Y, "Green") == ButtonBrightness.Full)
+ return true;
+ else
+ return false;
+ case animationColorMode.Red2Red:
+ if (getFieldColor(p.X, p.Y, "Red") == ButtonBrightness.Full)
+ return true;
+ else
+ return false;
+ case animationColorMode.Red2Green:
+ if (getFieldColor(p.X, p.Y, "Red") == ButtonBrightness.Full)
+ return true;
+ else
+ return false;
+ default:
+ return false;
+
+ }
+
+ }
+
+ private void refreshGroupColors(Point[] currentGroup)
+ {
+ //Depending on Colormode refresh the Brightness of that button group
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ setFieldColor(Tile.X, Tile.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Full);
+ }
+ break;
+ case animationColorMode.Green2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ setFieldColor(Tile.X, Tile.Y, "Green2Red", ButtonBrightness.Off, ButtonBrightness.Full);
+ }
+ break;
+ case animationColorMode.Red2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ setFieldColor(Tile.X, Tile.Y, "Red2Green", ButtonBrightness.Full, ButtonBrightness.Off);
+ }
+ break;
+ case animationColorMode.Red2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ setFieldColor(Tile.X, Tile.Y, "Red", ButtonBrightness.Full, ButtonBrightness.Off);
+ }
+ break;
+ }
+
+ }
+
+ private void increaseGroupColors(Point[] currentGroup)
+ {
+ // Depending on colormode decay
+
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (getFieldColor(Tile.X, Tile.Y, "Green"))
+ {
+ case ButtonBrightness.Off:
+ setFieldColor(Tile.X, Tile.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Medium:
+ setFieldColor(Tile.X, Tile.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ case ButtonBrightness.Low:
+ setFieldColor(Tile.X, Tile.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Medium);
+ break;
+
+ }
+ }
+ break;
+ case animationColorMode.Green2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (getFieldColor(Tile.X, Tile.Y, "Green"))
+ {
+ case ButtonBrightness.Off:
+ setFieldColor(Tile.X, Tile.Y, "Green2Red", ButtonBrightness.Medium, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Medium:
+ setFieldColor(Tile.X, Tile.Y, "Green2Red", ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+ case ButtonBrightness.Low:
+ setFieldColor(Tile.X, Tile.Y, "Green2Red", ButtonBrightness.Low, ButtonBrightness.Medium);
+ break;
+
+ }
+ }
+ break;
+ case animationColorMode.Red2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (getFieldColor(Tile.X, Tile.Y, "Red"))
+ {
+ case ButtonBrightness.Off:
+ setFieldColor(Tile.X, Tile.Y, "Red2Green", ButtonBrightness.Low, ButtonBrightness.Medium);
+ break;
+ case ButtonBrightness.Medium:
+ setFieldColor(Tile.X, Tile.Y, "Red2Green", ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Low:
+ setFieldColor(Tile.X, Tile.Y, "Red2Green", ButtonBrightness.Medium, ButtonBrightness.Low);
+ break;
+
+ }
+
+
+ }
+ break;
+ case animationColorMode.Red2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (getFieldColor(Tile.X, Tile.Y, "Red"))
+ {
+ case ButtonBrightness.Off:
+ setFieldColor(Tile.X, Tile.Y, "Red", ButtonBrightness.Low, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Medium:
+ setFieldColor(Tile.X, Tile.Y, "Red", ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Low:
+ setFieldColor(Tile.X, Tile.Y, "Red", ButtonBrightness.Medium, ButtonBrightness.Off);
+ break;
+
+ }
+
+ }
+ break;
+ }
+ }
+
+ private void decayGroupColors(Point[] currentGroup)
+ {
+ // Depending on colormode decay
+
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (getFieldColor(Tile.X, Tile.Y, "Green"))
+ {
+ case ButtonBrightness.Full:
+ setFieldColor(Tile.X, Tile.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Medium);
+ break;
+ case ButtonBrightness.Medium:
+ setFieldColor(Tile.X, Tile.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Low:
+ setFieldColor(Tile.X, Tile.Y, "Green", ButtonBrightness.Off, ButtonBrightness.Off);
+ break;
+
+ }
+ }
+ break;
+ case animationColorMode.Green2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (getFieldColor(Tile.X, Tile.Y, "Green"))
+ {
+ case ButtonBrightness.Full:
+ setFieldColor(Tile.X, Tile.Y, "Green2Red", ButtonBrightness.Low, ButtonBrightness.Medium);
+ break;
+ case ButtonBrightness.Medium:
+ setFieldColor(Tile.X, Tile.Y, "Green2Red", ButtonBrightness.Medium, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Low:
+ setFieldColor(Tile.X, Tile.Y, "Green2Red", ButtonBrightness.Full, ButtonBrightness.Off);
+ break;
+
+ }
+ }
+ break;
+ case animationColorMode.Red2Green:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (getFieldColor(Tile.X, Tile.Y, "Red"))
+ {
+ case ButtonBrightness.Full:
+ setFieldColor(Tile.X, Tile.Y, "Red2Green", ButtonBrightness.Medium, ButtonBrightness.Low);
+ break;
+ case ButtonBrightness.Medium:
+ setFieldColor(Tile.X, Tile.Y, "Red2Green", ButtonBrightness.Low, ButtonBrightness.Medium);
+ break;
+ case ButtonBrightness.Low:
+ setFieldColor(Tile.X, Tile.Y, "Red2Green", ButtonBrightness.Off, ButtonBrightness.Full);
+ break;
+
+ }
+
+
+ }
+ break;
+ case animationColorMode.Red2Red:
+ foreach (Point Tile in currentGroup)
+ {
+ switch (getFieldColor(Tile.X, Tile.Y, "Red"))
+ {
+ case ButtonBrightness.Full:
+ setFieldColor(Tile.X, Tile.Y,"Red", ButtonBrightness.Medium, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Medium:
+ setFieldColor(Tile.X, Tile.Y, "Red", ButtonBrightness.Low, ButtonBrightness.Off);
+ break;
+ case ButtonBrightness.Low:
+ setFieldColor(Tile.X, Tile.Y, "Red", ButtonBrightness.Off, ButtonBrightness.Off);
+ break;
+
+ }
+
+ }
+ break;
+ }
+ }
+
+ private void fillFieldValues(int Seed)
+ {
+ // This method sets up the values behind all fields to build paths on; every field is unique
+ // and stays the same per private key
+ FieldValRandomizer = new Random(Seed);
+
+ for (int yPos = 0; yPos < 8; yPos++)
+ {
+ for (int xPos = 0; xPos < 8; xPos++)
+ {
+ FieldValues[xPos, yPos] = FieldValRandomizer.Next(0, 100);
+ Console.Write(FieldValues[xPos, yPos] + " |");
+ }
+ Console.WriteLine("");
+ }
+ }
+
+ private void fillVirtualGrid()
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ virtualButton tempButton = new virtualButton();
+ tempButton.PosX = i;
+ tempButton.PosY = j;
+ tempButton.IntensityGreen = ButtonBrightness.Off;
+ tempButton.IntensityRed = ButtonBrightness.Off;
+ virtualGrid[i, j] = tempButton;
+ }
+ }
+
+ switch (currentMode)
+ {
+ case animationColorMode.Green2Green:
+ case animationColorMode.Green2Red:
+ virtualGrid[3, 3].IntensityRed = ButtonBrightness.Full;
+ virtualGrid[3, 3].IntensityGreen = ButtonBrightness.Off;
+ virtualGrid[3, 4].IntensityRed = ButtonBrightness.Full;
+ virtualGrid[3, 4].IntensityGreen = ButtonBrightness.Off;
+ virtualGrid[4, 3].IntensityRed = ButtonBrightness.Full;
+ virtualGrid[4, 3].IntensityGreen = ButtonBrightness.Off;
+ virtualGrid[4, 4].IntensityRed = ButtonBrightness.Full;
+ virtualGrid[4, 4].IntensityGreen = ButtonBrightness.Off;
+ break;
+ case animationColorMode.Red2Green:
+ case animationColorMode.Red2Red:
+ virtualGrid[3, 3].IntensityRed = ButtonBrightness.Off;
+ virtualGrid[3, 3].IntensityGreen = ButtonBrightness.Full;
+ virtualGrid[3, 4].IntensityRed = ButtonBrightness.Off;
+ virtualGrid[3, 4].IntensityGreen = ButtonBrightness.Full;
+ virtualGrid[4, 3].IntensityRed = ButtonBrightness.Off;
+ virtualGrid[4, 3].IntensityGreen = ButtonBrightness.Full;
+ virtualGrid[4, 4].IntensityRed = ButtonBrightness.Off;
+ virtualGrid[4, 4].IntensityGreen = ButtonBrightness.Full;
+ break;
+ }
+
+
+
+ }
+
+ private void setFieldColor(int PosX, int PosY, string color, ButtonBrightness intensityR,ButtonBrightness intensityG )
+ {
+ if (mLaunchpadDevice == null)
+ {//no device was given so virtualBoard is used
+ virtualGrid[PosX, PosY].IntensityGreen = intensityG;
+ virtualGrid[PosX, PosY].IntensityRed = intensityR;
+
+ }
+ else
+ {
+ mLaunchpadDevice[PosX, PosY].SetBrightness(intensityR, intensityG);
+ }
+ }
+
+ public ButtonBrightness getFieldColor(int PosX, int PosY, string neededColor)
+ {
+ ButtonBrightness TempColor;
+ if (mLaunchpadDevice == null)
+ {//no device was given so virtualBoard is used
+ switch (neededColor)
+ {
+ case "Red":
+ TempColor = virtualGrid[PosX, PosY].IntensityRed;
+ break;
+ case "Green":
+ TempColor = virtualGrid[PosX, PosY].IntensityGreen;
+ break;
+ default:
+ TempColor = ButtonBrightness.Off;
+ break;
+
+ }
+ return TempColor;
+ }
+ else
+ {
+ switch (neededColor)
+ {
+ case "Red":
+ TempColor = mLaunchpadDevice[PosX, PosY].RedBrightness;
+ break;
+ case "Green":
+ TempColor = mLaunchpadDevice[PosX, PosY].GreenBrightness;
+ break;
+ default:
+ TempColor = ButtonBrightness.Off;
+ break;
+
+ }
+
+ return TempColor;
+ }
+ }
+
+ private string createPathChar(string codepage)
+ {
+ //This method creates a codepage char to add it to the current path
+ int tempValue = 0;
+ string tempString;
+ int lowerCap = 0;
+ int upperCap = 0;
+ char c = ' ';
+ switch (codepage)
+ {
+ // ToDo: Insert Codepage specific caps + find out how to cast INTs to them
+ case "ASCII":
+ case "UTF-16":
+ case "65001 UTF-8 (Unicode)":
+ switch (characterSet)
+ {
+ case "Nur Buchstaben":
+ lowerCap = 65;
+ upperCap = 121;
+ break;
+ case "Nur Zahlen":
+ lowerCap = 48;
+ upperCap = 58;
+ break;
+ case "Keine Steuerzeichen":
+ default:
+ lowerCap = 32;
+ upperCap = 126;
+ break;
+ }
+
+ break;
+ }
+ //Pick a valid codepage-value which is allowed by target system (needs to be ensured beforehand!!)
+ //because 0 can be a FieldValue too, at least 1 charactervalue needs to be generated
+ if (characterSet == "Nur Buchstaben")
+ {
+ //in characters only mode there are codepages (like ascii/Unicode) which do not have all chars grouped together
+ //for such codepages there must be a special tempValue-Calc procedure
+ bool characterIsInvalid = true;
+ switch (codePage)
+ {
+ case "65001 UTF-8 (Unicode)":
+ default:
+ for (int indexer = -1; indexer < FieldValues[currentTrailPoint.X, currentTrailPoint.Y] || characterIsInvalid; indexer++)
+ {
+ //lower and uppder cap have all chars implemented but only valid chars need allow for continuing of the process
+ tempValue = CharValRandomizer.Next(lowerCap, upperCap);
+ c = (char)tempValue;
+
+ switch (c)
+ {
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ case 'X':
+ case 'Y':
+ case 'Z':
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ case 'i':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 's':
+ case 't':
+ case 'u':
+ case 'v':
+ case 'w':
+ case 'x':
+ case 'y':
+ case 'z':
+ characterIsInvalid = false;
+ break;
+ default:
+ characterIsInvalid = true;
+ break;
+ }
+
+ }
+ break;
+ }
+
+ }
+ else
+ {
+ // If searched chars are grouped together this process is enough to determine all needed chars
+ for (int indexer = -1; indexer < FieldValues[currentTrailPoint.X, currentTrailPoint.Y]; indexer++)
+ {
+ tempValue = CharValRandomizer.Next(lowerCap, upperCap);
+ }
+
+ c = (char)tempValue;
+ }
+
+ if (c == '\\')
+ {
+ tempString = c.ToString();
+ tempString += c.ToString();
+ }
+
+ return c.ToString();
+ }
+
+ private void createImageFromPoint(Point nextImage)
+ {
+
+ string Tempstring = nextImage.X.ToString() + "_" + nextImage.Y.ToString();
+ string PathString = "../../Assets/Graphics/";
+ string extension = ".png";
+ string proccessString;
+ if (processMode == "Horizontal_Green")
+ proccessString = "Hor_";
+ else
+ proccessString = "Ver_";
+ string finalPath = PathString + proccessString + Tempstring + extension;
+ ImageList.Enqueue(finalPath);
+ }
+
+
+
+ private void Draw()
+ {
+ // Refresh devices light information
+ mLaunchpadDevice.Refresh();
+ }
+
+ public string GetFinalPassword()
+ {
+ return finalPassword;
+ }
+
+ public Queue GetInstructionList()
+ {
+ return ImageList;
+ }
+
+ public void clearAllFields()
+ {
+ //Clear all Grid Fields
+ for (int yPos = 0; yPos < 8; yPos++)
+ {
+ for (int xPos = 0; xPos < 8; xPos++)
+ {
+ mLaunchpadDevice[xPos, xPos].TurnOffLight();
+ }
+ }
+
+ //ToolbarButtons
+ mLaunchpadDevice.GetButton(ToolbarButton.Down).TurnOffLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.Left).TurnOffLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.Mixer).TurnOffLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.Right).TurnOffLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).TurnOffLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.Up).TurnOffLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.User1).TurnOffLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.User2).TurnOffLight();
+
+ //SidebarButtons
+ mLaunchpadDevice.GetButton(SideButton.Arm).TurnOffLight();
+ mLaunchpadDevice.GetButton(SideButton.Pan).TurnOffLight();
+ mLaunchpadDevice.GetButton(SideButton.Solo).TurnOffLight();
+ mLaunchpadDevice.GetButton(SideButton.SoundA).TurnOffLight();
+ mLaunchpadDevice.GetButton(SideButton.SoundB).TurnOffLight();
+ mLaunchpadDevice.GetButton(SideButton.Stop).TurnOffLight();
+ mLaunchpadDevice.GetButton(SideButton.TrackOn).TurnOffLight();
+ mLaunchpadDevice.GetButton(SideButton.Volume).TurnOffLight();
+
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/Program.cs b/launchpad-master/IntelOrca.LaunchpadTests/Program.cs
new file mode 100644
index 0000000..406cd55
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/Program.cs
@@ -0,0 +1,90 @@
+using IntelOrca.Launchpad;
+using System;
+
+namespace IntelOrca.LaunchpadTests
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ LaunchpadDevice device;
+
+ Console.WriteLine("Launchpad Tests");
+ Console.WriteLine("Ted John 2013");
+ Console.WriteLine("");
+
+ try
+ {
+ device = new LaunchpadDevice();
+ device.DoubleBuffered = true;
+
+ Console.WriteLine("Launchpad found");
+ }
+ catch
+ {
+ Console.WriteLine("No launchpad found");
+ Console.ReadLine();
+ return;
+ }
+
+ Console.WriteLine("");
+ Console.WriteLine("0: Grid toggle");
+ Console.WriteLine("1: Scrolling message");
+ Console.WriteLine("2: Bulldog");
+ Console.WriteLine("3: Rain sequencer");
+ Console.WriteLine("4: Reversi");
+ Console.WriteLine("5: Snake");
+ Console.WriteLine("6: Geometrische Tests");
+ Console.WriteLine("7: Super Safe Password Generator");
+
+ int i;
+ while (!Int32.TryParse(Console.ReadLine(), out i))
+ {
+ Console.WriteLine("Try again...");
+ }
+
+ switch (i)
+ {
+ case 0:
+ ToggleGrid toggleGrid = new ToggleGrid(device);
+ toggleGrid.Run();
+ break;
+ case 1:
+ Console.Write("Type a message:");
+ string message = Console.ReadLine();
+
+ ScrollingLetters scrollingLetters = new ScrollingLetters(device);
+ scrollingLetters.Text = message.ToUpper();
+ scrollingLetters.ScrollText();
+ break;
+ case 2:
+ Bulldog bulldog = new Bulldog(device);
+ bulldog.Play();
+ break;
+ case 3:
+ RainSequencer rain = new RainSequencer(device);
+ rain.Run();
+ break;
+ case 4:
+ Reversi reversi = new Reversi(device);
+ reversi.Run();
+ break;
+ case 5:
+ Snake snake = new Snake(device);
+ snake.Run();
+ break;
+ case 6:
+ GeometrischeTests geoTest = new GeometrischeTests(device);
+ geoTest.Run();
+ break;
+ case 7:
+ PWGenerator pwGen = new PWGenerator(device);
+ pwGen.Run();
+ break;
+ default:
+ Console.WriteLine("No such application");
+ break;
+ }
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/Properties/AssemblyInfo.cs b/launchpad-master/IntelOrca.LaunchpadTests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..45d24de
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("IntelOrca.LaunchpadTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("IntelOrca.LaunchpadTests")]
+[assembly: AssemblyCopyright("Copyright © Ted John 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3ca042d4-ea08-4d51-a0c7-1f1ef0ece762")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/RainSequencer.cs b/launchpad-master/IntelOrca.LaunchpadTests/RainSequencer.cs
new file mode 100644
index 0000000..2ebc65d
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/RainSequencer.cs
@@ -0,0 +1,266 @@
+using IntelOrca.Launchpad;
+using Midi;
+using System;
+using System.Threading;
+
+namespace IntelOrca.LaunchpadTests
+{
+ class RainSequencer
+ {
+ const int NumCols = 16;
+ const int NumRows = 8;
+
+ private LaunchpadDevice mLaunchpadDevice;
+
+ private bool[,] mSequence = new bool[NumCols, NumRows];
+ private bool[] mRemove = new bool[NumCols];
+ private int mSequenceOffset;
+ private int mColumnOffset;
+ private int mMode, mSoundType;
+ private int mConfirmTime;
+ private bool mForceDraw;
+
+ private int mTempo = 8 * 60;
+
+ OutputDevice mOutputDevice;
+ private int mInstrument = 0;
+ private int mPercussion = 0;
+
+ public RainSequencer(LaunchpadDevice device)
+ {
+ mLaunchpadDevice = device;
+ mOutputDevice = OutputDevice.InstalledDevices[0];
+ mOutputDevice.Open();
+
+ mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
+
+/*
+ Random rand = new Random();
+ for (int y = 0; y < NumRows; y++)
+ for (int x = 0; x < NumRows; x++)
+ if (rand.Next(0, 12) == 0)
+ mSequence[x, y] = true;
+ * */
+ }
+
+ private int SeqYtoButtonY(int y)
+ {
+ return 0;
+ }
+
+ private int ButtonYtoSeqY(int y)
+ {
+ return (y + NumRows - mSequenceOffset) % NumRows;
+ }
+
+ private int ButtonXtoColX(int x)
+ {
+ return (x + NumCols - mColumnOffset) % NumCols;
+ }
+
+ private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e)
+ {
+ if (e.Type == ButtonType.Grid) {
+ if (e.Y == 7) {
+ mRemove[ButtonXtoColX(e.X)] = !mRemove[ButtonXtoColX(e.X)];
+ if (mMode == 1)
+ PlayNoise(e.X);
+ } else {
+ mSequence[ButtonXtoColX(e.X), ButtonYtoSeqY(e.Y)] = !mSequence[ButtonXtoColX(e.X), ButtonYtoSeqY(e.Y)];
+ }
+
+ mForceDraw = true;
+ } else if (e.Type == ButtonType.Toolbar) {
+ switch (e.ToolbarButton) {
+ case ToolbarButton.Up:
+ mSequenceOffset = (mSequenceOffset + NumRows - 1) % NumRows;
+ break;
+ case ToolbarButton.Down:
+ mSequenceOffset = (mSequenceOffset + 1) % NumRows;
+ break;
+ case ToolbarButton.Left:
+ mColumnOffset = (mColumnOffset + NumCols - 1) % NumCols;
+ break;
+ case ToolbarButton.Right:
+ mColumnOffset = (mColumnOffset + 1) % NumCols;
+ break;
+ case ToolbarButton.Mixer:
+ mMode = (mMode == 0 ? 1 : 0);
+ break;
+ case ToolbarButton.Session:
+ if (mConfirmTime > 0) {
+ for (int y = 0; y < NumRows; y++)
+ for (int x = 0; x < NumCols; x++)
+ mSequence[x, y] = false;
+ mConfirmTime = 0;
+ } else {
+ mConfirmTime = 1000;
+ }
+ break;
+ }
+ mForceDraw = true;
+ } else if (e.Type == ButtonType.Side) {
+ switch (e.SidebarButton) {
+ case SideButton.Volume:
+ if (mTempo < 1980)
+ mTempo += 20;
+ break;
+ case SideButton.Pan:
+ if (mTempo > 20)
+ mTempo -= 20;
+ break;
+ case SideButton.SoundA:
+ if (mSoundType == 0) {
+ mPercussion = (mPercussion + 1) % (Percussion.OpenTriangle - Percussion.BassDrum2 + 1);
+ mOutputDevice.SendProgramChange(Channel.Channel1, (Instrument)mInstrument);
+ } else {
+ mSoundType = 0;
+ }
+ break;
+ case SideButton.SoundB:
+ if (mSoundType == 1) {
+ mInstrument = (mInstrument + 1) % 127;
+ mOutputDevice.SendProgramChange(Channel.Channel1, (Instrument)mInstrument);
+ } else {
+ mSoundType = 1;
+ }
+ break;
+ case SideButton.Arm:
+ mSequenceOffset = 0;
+ mColumnOffset = 0;
+ break;
+ }
+ }
+ }
+
+ public void Run()
+ {
+ long last_tick = Environment.TickCount;
+ long delay = 1;
+ long duration = 0;
+
+ while (true) {
+ delay = (int)(1000.0 / (mTempo / 60.0));
+ duration = Environment.TickCount - last_tick;
+ if (duration < delay) {
+ if (mForceDraw) {
+ Draw();
+ mForceDraw = false;
+ }
+
+ continue;
+ }
+ last_tick = Environment.TickCount;
+ mConfirmTime = Math.Max(0, mConfirmTime - (int)duration);
+
+ Update();
+ Draw();
+ }
+ }
+
+ private void PlayNoise(int tone)
+ {
+ new Thread(new ThreadStart(() => {
+ if (mSoundType == 0) {
+ mOutputDevice.SendPercussion(Percussion.BassDrum2 + mPercussion + tone, 127);
+ } else {
+ mOutputDevice.SendNoteOn(Channel.Channel1, Pitch.A4 + tone, 127);
+ Thread.Sleep((int)(1000.0 / (mTempo / 60.0)));
+ mOutputDevice.SendNoteOff(Channel.Channel1, Pitch.A4 + tone, 127);
+ }
+
+ // Console.Beep(100 * (tone + 3), 100);
+ })).Start();
+ }
+
+ private void DiscardRedBeats()
+ {
+ int y = ButtonYtoSeqY(7);
+ for (int x = 0; x < NumCols; x++)
+ if (mSequence[x, y] && mRemove[x])
+ mSequence[x, y] = false;
+ }
+
+ private void PlayBeats()
+ {
+ int y = ButtonYtoSeqY(7);
+ for (int x = 0; x < NumCols; x++)
+ if (mSequence[x, y])
+ PlayNoise(x);
+ }
+
+ private void Update()
+ {
+ if (mMode == 1)
+ return;
+
+ DiscardRedBeats();
+ mSequenceOffset = (mSequenceOffset + 1) % NumRows;
+ PlayBeats();
+ }
+
+ private void Draw()
+ {
+ ButtonBrightness[,] redgrid = new ButtonBrightness[8, 8];
+ ButtonBrightness[,] greengrid = new ButtonBrightness[8, 8];
+
+ for (int y = 0; y < 7; y++)
+ for (int x = 0; x < 8; x++)
+ if (mSequence[ButtonXtoColX(x), ButtonYtoSeqY(y)])
+ redgrid[x, y] = greengrid[x, y] = ButtonBrightness.Full;
+
+ for (int x = 0; x < 8; x++) {
+ ButtonBrightness brightness = (mSequence[ButtonXtoColX(x), ButtonYtoSeqY(7)] ? ButtonBrightness.Full : ButtonBrightness.Low);
+
+ if (!mRemove[ButtonXtoColX(x)])
+ greengrid[x, 7] = brightness;
+ else
+ redgrid[x, 7] = brightness;
+ }
+
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ mLaunchpadDevice[x, y].SetBrightness(redgrid[x, y], greengrid[x, y]);
+
+ if (mConfirmTime > 0)
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).TurnOnLight();
+ else
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).TurnOffLight();
+
+ if (mMode == 1)
+ mLaunchpadDevice.GetButton(ToolbarButton.Mixer).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ else
+ mLaunchpadDevice.GetButton(ToolbarButton.Mixer).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+
+ if (mSoundType == 0) {
+ mLaunchpadDevice.GetButton(SideButton.SoundA).TurnOnLight();
+ mLaunchpadDevice.GetButton(SideButton.SoundB).TurnOffLight();
+ } else {
+ mLaunchpadDevice.GetButton(SideButton.SoundA).TurnOffLight();
+ mLaunchpadDevice.GetButton(SideButton.SoundB).TurnOnLight();
+ }
+
+ mLaunchpadDevice.GetButton(ToolbarButton.Up).TurnOnLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.Down).TurnOnLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.Left).TurnOnLight();
+ mLaunchpadDevice.GetButton(ToolbarButton.Right).TurnOnLight();
+
+ mLaunchpadDevice.GetButton(SideButton.Volume).TurnOnLight();
+ mLaunchpadDevice.GetButton(SideButton.Pan).TurnOnLight();
+ mLaunchpadDevice.GetButton(SideButton.Arm).TurnOnLight();
+
+ mLaunchpadDevice.Refresh();
+
+ Console.SetCursorPosition(0, 0);
+ for (int y = 0; y < NumRows; y++) {
+ for (int x = 0; x < NumCols; x++) {
+ if (mSequence[x, y])
+ Console.Write("X");
+ else
+ Console.Write(".");
+ }
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/Reversi.cs b/launchpad-master/IntelOrca.LaunchpadTests/Reversi.cs
new file mode 100644
index 0000000..1e54c48
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/Reversi.cs
@@ -0,0 +1,279 @@
+using IntelOrca.Launchpad;
+using Midi;
+using System;
+using System.Collections.Generic;
+
+namespace IntelOrca.LaunchpadTests
+{
+ class Reversi
+ {
+ private Random mRandom = new Random();
+
+ private LaunchpadDevice mLaunchpadDevice;
+ private int[,] mGrid = new int[8, 8];
+ private int mPlayerTurn = 1;
+ private int mPlayerWinning = 0;
+
+ private int mConfirmTime;
+ private bool mForceDraw;
+ private int mGameState = 0;
+ private bool mShowPossibleMoves = true;
+ private bool mSolo = false;
+
+ private int mFlashCounter = 0;
+
+ private List> mPossiblePlaces = new List>();
+
+ OutputDevice mOutputDevice;
+
+ public Reversi(LaunchpadDevice device)
+ {
+ mLaunchpadDevice = device;
+
+ mLaunchpadDevice.DoubleBuffered = false;
+ mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
+
+ mOutputDevice = OutputDevice.InstalledDevices[0];
+ mOutputDevice.Open();
+
+ Restart();
+ }
+
+ private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e)
+ {
+ if (e.Type == ButtonType.Grid) {
+ if (CanPlaceAt(e.X, e.Y))
+ PlaceAt(e.X, e.Y);
+ } else if (e.Type == ButtonType.Side) {
+ if (e.SidebarButton == SideButton.TrackOn) {
+ mShowPossibleMoves = !mShowPossibleMoves;
+ mForceDraw = true;
+ } else if (e.SidebarButton == SideButton.Solo) {
+ mSolo = !mSolo;
+ }
+ } else if (e.Type == ButtonType.Toolbar) {
+ if (e.ToolbarButton == ToolbarButton.Session) {
+ if (mConfirmTime > 0) {
+ Restart();
+ mConfirmTime = 0;
+ } else {
+ mConfirmTime = 1000;
+ }
+ }
+ }
+ }
+
+ private void Restart()
+ {
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ mGrid[x, y] = 0;
+
+ mGrid[3, 3] = 1;
+ mGrid[4, 3] = 2;
+ mGrid[3, 4] = 2;
+ mGrid[4, 4] = 1;
+ mGameState = 0;
+ SetPlayerGo(1);
+
+ mOutputDevice.SendPercussion(Percussion.LongWhistle, 127);
+ }
+
+ private bool CanPlaceAt(int x, int y)
+ {
+ if (mGrid[x, y] != 0)
+ return false;
+
+ for (int dy = -1; dy <= 1; dy++)
+ for (int dx = -1; dx <= 1; dx++)
+ if (CheckDirection(x, y, dx, dy))
+ return true;
+
+ return false;
+ }
+
+ private bool CheckDirection(int x, int y, int dx, int dy, int state = 0)
+ {
+ x += dx;
+ y += dy;
+ if (!InBounds(x, y))
+ return false;
+ if (state == 0) {
+ if (mGrid[x, y] == 0 || mGrid[x, y] == mPlayerTurn)
+ return false;
+ return CheckDirection(x, y, dx, dy, 1);
+ } else if (state == 1) {
+ if (mGrid[x, y] == 0)
+ return false;
+ if (mGrid[x, y] == mPlayerTurn)
+ return true;
+ return CheckDirection(x, y, dx, dy, 1);
+ }
+
+ return false;
+ }
+
+ private bool InBounds(int x, int y)
+ {
+ return (x >= 0 && y >= 0 && x < 8 && y < 8);
+ }
+
+ private void PlaceAt(int x, int y)
+ {
+ if (mPlayerTurn == 1)
+ mOutputDevice.SendPercussion(Percussion.SnareDrum1, 127);
+ else if (mPlayerTurn == 2)
+ mOutputDevice.SendPercussion(Percussion.SnareDrum2, 127);
+
+ for (int dy = -1; dy <= 1; dy++)
+ for (int dx = -1; dx <= 1; dx++)
+ if (CheckDirection(x, y, dx, dy))
+ SwapDirection(x, y, dx, dy);
+
+ mGrid[x, y] = mPlayerTurn;
+ SetPlayerGo((mPlayerTurn == 1 ? 2 : 1));
+ }
+
+ private void SwapDirection(int x, int y, int dx, int dy)
+ {
+ x += dx;
+ y += dy;
+ if (mGrid[x, y] != mPlayerTurn) {
+ mGrid[x, y] = mPlayerTurn;
+ SwapDirection(x, y, dx, dy);
+ }
+ }
+
+ private void UpdatePossiblePlaces()
+ {
+ mPossiblePlaces.Clear();
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ if (CanPlaceAt(x, y))
+ mPossiblePlaces.Add(new Tuple(x, y));
+ }
+
+ private void SetPlayerGo(int n)
+ {
+ mPlayerTurn = n;
+ UpdatePossiblePlaces();
+ if (mPossiblePlaces.Count == 0) {
+ mPlayerTurn = (mPlayerTurn == 1 ? 2 : 1);
+ UpdatePossiblePlaces();
+ if (mPossiblePlaces.Count == 0) {
+ mGameState = 1;
+ mConfirmTime = int.MaxValue;
+ mOutputDevice.SendPercussion(Percussion.CrashCymbal1, 127);
+ }
+ }
+ mPlayerWinning = GetWinner();
+
+ if (mPossiblePlaces.Count > 0 && mSolo && mPlayerTurn == 2) {
+ int p = mRandom.Next(0, mPossiblePlaces.Count);
+ PlaceAt(mPossiblePlaces[p].Item1, mPossiblePlaces[p].Item2);
+ }
+
+ mForceDraw = true;
+ }
+
+ private int GetWinner()
+ {
+ int p1 = 0, p2 = 0;
+ for (int y = 0; y < 8; y++) {
+ for (int x = 0; x < 8; x++) {
+ if (mGrid[x, y] == 1)
+ p1++;
+ else if (mGrid[x, y] == 2)
+ p2++;
+ }
+ }
+ if (p1 > p2)
+ return 1;
+ else if (p2 > p1)
+ return 2;
+ else
+ return 0;
+ }
+
+ public void Run()
+ {
+ long last_tick = Environment.TickCount;
+ long delay = 1;
+ long duration = 0;
+
+ while (true) {
+ delay = (int)(1000.0 / 60.0);
+ duration = Environment.TickCount - last_tick;
+ if (duration < delay) {
+ if (mForceDraw) {
+ Draw();
+ mForceDraw = false;
+ }
+
+ continue;
+ }
+ last_tick = Environment.TickCount;
+ mConfirmTime = Math.Max(0, mConfirmTime - (int)duration);
+ mFlashCounter = (mFlashCounter + 1) % 20;
+
+ Draw();
+ }
+ }
+
+ private void Draw()
+ {
+ ButtonBrightness[,] redgrid = new ButtonBrightness[8, 8];
+ ButtonBrightness[,] greengrid = new ButtonBrightness[8, 8];
+
+ for (int y = 0; y < 8; y++) {
+ for (int x = 0; x < 8; x++) {
+ if (mGrid[x, y] == 1) {
+ redgrid[x, y] = ButtonBrightness.Full;
+ } else if (mGrid[x, y] == 2) {
+ greengrid[x, y] = ButtonBrightness.Full;
+ } else if (mShowPossibleMoves && mFlashCounter < 10) {
+ if (mPossiblePlaces.Exists(p => p.Item1 == x && p.Item2 == y)) {
+ redgrid[x, y] = ButtonBrightness.Low;
+ greengrid[x, y] = ButtonBrightness.Low;
+ }
+ }
+ }
+ }
+
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ mLaunchpadDevice[x, y].SetBrightness(redgrid[x, y], greengrid[x, y]);
+
+ if (mPlayerTurn == 1) {
+ mLaunchpadDevice.GetButton(ToolbarButton.User1).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice.GetButton(ToolbarButton.User2).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+ } else if (mPlayerTurn == 2) {
+ mLaunchpadDevice.GetButton(ToolbarButton.User1).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+ mLaunchpadDevice.GetButton(ToolbarButton.User2).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ }
+
+ if (mPlayerWinning == 1) {
+ mLaunchpadDevice.GetButton(ToolbarButton.Mixer).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ } else if (mPlayerWinning == 2) {
+ mLaunchpadDevice.GetButton(ToolbarButton.Mixer).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ } else {
+ mLaunchpadDevice.GetButton(ToolbarButton.Mixer).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+ }
+
+ if (mShowPossibleMoves)
+ mLaunchpadDevice.GetButton(SideButton.TrackOn).TurnOnLight();
+ else
+ mLaunchpadDevice.GetButton(SideButton.TrackOn).TurnOffLight();
+
+ if (mConfirmTime > 0)
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).TurnOnLight();
+ else
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).TurnOffLight();
+
+ if (mSolo)
+ mLaunchpadDevice.GetButton(SideButton.Solo).TurnOnLight();
+ else
+ mLaunchpadDevice.GetButton(SideButton.Solo).TurnOffLight();
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/ScrollingLetters.cs b/launchpad-master/IntelOrca.LaunchpadTests/ScrollingLetters.cs
new file mode 100644
index 0000000..03597ef
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/ScrollingLetters.cs
@@ -0,0 +1,177 @@
+using IntelOrca.Launchpad;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace IntelOrca.LaunchpadTests
+{
+ class ScrollingLetters
+ {
+ class CharacterDefinition
+ {
+ private char mKey;
+ private int mWidth;
+ private int mHeight;
+ private List mPoints = new List();
+
+ public CharacterDefinition(StringReader sr)
+ {
+ string key;
+
+ // Read key
+ while ((key = sr.ReadLine()).Length == 0);
+ mKey = key[0];
+
+ // Read characters
+ mHeight = 5;
+ for (int y = 0; y < mHeight; y++) {
+ string line = sr.ReadLine();
+ for (int x = 0; x < line.Length; x++)
+ if (line[x] == 'X')
+ mPoints.Add(new Point(x, y));
+ }
+
+ mWidth = mPoints.Max(p => p.X) + 1;
+ }
+
+ public override int GetHashCode()
+ {
+ return mKey.GetHashCode();
+ }
+
+ public char Key
+ {
+ get { return mKey; }
+ }
+
+ public int Width
+ {
+ get { return mWidth; }
+ set { mWidth = value; }
+ }
+
+ public int Height
+ {
+ get { return mHeight; }
+ set { mHeight = value; }
+ }
+
+ public Point[] Points
+ {
+ get { return mPoints.ToArray(); }
+ }
+
+ public struct Point
+ {
+ public Point(int x, int y) : this() { X = x; Y = y; }
+
+ public int X { get; set; }
+ public int Y { get; set; }
+
+ public override string ToString()
+ {
+ return String.Format("X = {0} Y = {1}", X, Y);
+ }
+ }
+ }
+
+ private static Dictionary mCharacterDefinitions = GetCharacterDefinitions();
+
+ private LaunchpadDevice mLaunchpadDevice;
+ private string mText = String.Empty;
+ private int mTextOffset = 8;
+
+ private bool[,] mGrid = new bool[8, 8];
+
+ private static Dictionary GetCharacterDefinitions()
+ {
+ var defs = new Dictionary();
+
+ StringReader sr = new StringReader(File.ReadAllText("text.txt"));
+ while (sr.Peek() != -1) {
+ if (Char.IsWhiteSpace((char)sr.Peek())) {
+ sr.Read();
+ continue;
+ }
+
+ CharacterDefinition cd = new CharacterDefinition(sr);
+ defs.Add(cd.Key, cd);
+ }
+
+ return defs;
+ }
+
+ public ScrollingLetters(LaunchpadDevice device)
+ {
+ mLaunchpadDevice = device;
+ }
+
+ private void SetGrid(int x, int y, bool value)
+ {
+ if (x >= 0 && y >= 0 && x < 8 && y < 8)
+ mGrid[x, y] = value;
+ }
+
+ private int RenderCharacter(char c, int x, int y)
+ {
+ if (mCharacterDefinitions.ContainsKey(c)) {
+ CharacterDefinition cd = mCharacterDefinitions[c];
+ if (x + cd.Width >= 0 && x < 8)
+ Array.ForEach(cd.Points, p => SetGrid(x + p.X, y + p.Y, true));
+ return cd.Width;
+ }
+
+ return 4;
+ }
+
+ private void RenderGrid()
+ {
+ int x, y;
+
+ for (y = 0; y < 8; y++)
+ for (x = 0; x < 8; x++)
+ mGrid[x, y] = false;
+
+ x = mTextOffset;
+ y = 1;
+ foreach (char c in mText) {
+ x += RenderCharacter(c, x, y) + 1;
+ }
+
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 8; x++) {
+ if (mGrid[x, y])
+ mLaunchpadDevice[x, y].SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+ else
+ mLaunchpadDevice[x, y].SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+ }
+ }
+ mLaunchpadDevice.Refresh();
+ }
+
+ public void ScrollText()
+ {
+ long last_tick = 0;
+ long delay = 100;
+
+ while (true) {
+ if (Environment.TickCount - last_tick < delay)
+ continue;
+ last_tick = Environment.TickCount;
+
+ RenderGrid();
+
+ mTextOffset--;
+ if (mTextOffset < -(mText.Length * 5 + 2))
+ mTextOffset = 8;
+ }
+ }
+
+ public string Text
+ {
+ get { return mText; }
+ set { mText = value; }
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/Snake.cs b/launchpad-master/IntelOrca.LaunchpadTests/Snake.cs
new file mode 100644
index 0000000..bf7dc3c
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/Snake.cs
@@ -0,0 +1,233 @@
+using IntelOrca.Launchpad;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace IntelOrca.LaunchpadTests
+{
+ struct Point
+ {
+ public Point(int x, int y)
+ : this()
+ {
+ X = x;
+ Y = y;
+ }
+
+ public int X { get; set; }
+ public int Y { get; set; }
+ }
+
+ class Snake
+ {
+ private LaunchpadDevice mLaunchpadDevice;
+
+ private Random mRandom = new Random();
+ private long mCurrentTicks = 0;
+
+ private Point[] mBody;
+ private Point mDirection;
+
+ private bool mFoodActive;
+ private Point mFood;
+
+ private bool snakeFrozen = false;
+ private bool gameEnd = false;
+
+ public Snake(LaunchpadDevice device)
+ {
+ mLaunchpadDevice = device;
+
+ mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
+ mLaunchpadDevice.GetButton(SideButton.Arm).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ mLaunchpadDevice.GetButton(SideButton.Solo).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+
+ Restart();
+ }
+
+ private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e)
+ {
+ if (e.Type == ButtonType.Grid) {
+ mFood.X = e.X;
+ mFood.Y = e.Y;
+ mFoodActive = true;
+ }
+
+ if (e.Type == ButtonType.Side)
+ {
+ if(e.SidebarButton == SideButton.Solo)
+ {
+ if (snakeFrozen)
+ snakeFrozen = false;
+ else
+ snakeFrozen = true;
+ }
+ }
+
+ if (e.Type == ButtonType.Side)
+ {
+ if (e.SidebarButton == SideButton.Arm)
+ {
+ mLaunchpadDevice.Reset();
+ gameEnd = true;
+ }
+ }
+
+ }
+
+ public void Run()
+ {
+ // Kontrolle des internen Ticks (6*12 Frames werden pro "nächster" aktion verstreichen gelassen)
+ long last_tick = Environment.TickCount;
+ long delay = 12;
+ delay = 12 * 6;
+
+ // GameLoop
+ while (true && !gameEnd) {
+ if (Environment.TickCount - last_tick < delay)
+ continue;
+ mCurrentTicks += Environment.TickCount - last_tick;
+ last_tick = Environment.TickCount;
+
+ // Spielroutine (mit "Pause" Funktion [bei einem Snake Spiel natürlich quasi cheaten xD])
+ if(!snakeFrozen)
+ {
+ // Update aller Positionen
+ Update();
+ // Neu Zeichnen des Brettes
+ Draw();
+ }
+
+ }
+ }
+
+ private void Update()
+ {
+ SetSnakeDirection();
+ MoveSnake();
+ }
+
+ private void Draw()
+ {
+ ButtonBrightness[,] redgrid = new ButtonBrightness[8, 8];
+ ButtonBrightness[,] greengrid = new ButtonBrightness[8, 8];
+
+ // Draw snake
+ foreach (Point p in mBody)
+ if (InBounds(p))
+ greengrid[p.X, p.Y] = ButtonBrightness.Full;
+ if (InBounds(mBody[0]))
+ redgrid[mBody[0].X, mBody[0].Y] = ButtonBrightness.Full;
+
+ // Draw food
+ if (mFoodActive)
+ redgrid[mFood.X, mFood.Y] = ButtonBrightness.Full;
+
+ // Invalidate (Neu Zeichnen aller Kacheln anhand was in red/greengrid drin steht
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ mLaunchpadDevice[x, y].SetBrightness(redgrid[x, y], greengrid[x, y]);
+ // Refresh um neue Konstellation anzuzeigen
+ mLaunchpadDevice.Refresh();
+ }
+
+ private void Restart()
+ {
+ mBody = new Point[4];
+ for (int y = 8; y < 8 + 4; y++)
+ mBody[y - 8] = new Point(3, y);
+ mDirection = new Point(0, -1);
+
+ mFoodActive = false;
+
+ // PlaceFood();
+ }
+
+ private void MoveSnake()
+ {
+ // Nachrücken aller Steine nach vorne (Letzer wird entfernt)
+ for (int i = mBody.Length - 1; i > 0; i--)
+ mBody[i] = mBody[i - 1];
+ //Kopf wird in Richtung bewegt
+ mBody[0].X += mDirection.X;
+ mBody[0].Y += mDirection.Y;
+
+ // Wenn
+ for (int i = 1; i < mBody.Length; i++) {
+ if (mBody[0].X == mBody[i].X && mBody[0].Y == mBody[i].Y)
+ Restart();
+ }
+
+ if (mBody[0].X == mFood.X && mBody[0].Y == mFood.Y) {
+ mFoodActive = false;
+ ExtendSnake();
+ // PlaceFood();
+ }
+ }
+
+ public void SetSnakeDirection()
+ {
+ bool danger = false;
+
+ Point head = mBody[0];
+ if (head.X == 7 && mDirection.X > 0) {
+ if (head.Y < 7) mDirection = new Point(0, 1);
+ else mDirection = new Point(0, -1);
+ danger = true;
+ } else if (head.X == 0 && mDirection.X < 0) {
+ if (head.Y < 7) mDirection = new Point(0, 1);
+ else mDirection = new Point(0, -1);
+ danger = true;
+ }
+
+ if (head.Y == 7 && mDirection.Y > 0) {
+ if (head.X < 7) mDirection = new Point(1, 0);
+ else mDirection = new Point(-1, 0);
+ danger = true;
+ } else if (head.Y == 0 && mDirection.Y < 0) {
+ if (head.X < 7) mDirection = new Point(1, 0);
+ else mDirection = new Point(-1, 0);
+ danger = true;
+ }
+
+ if (!danger && mFoodActive) {
+ if (mDirection.X != 0) {
+ if (mBody[0].X == mFood.X) {
+ if (mBody[0].Y < mFood.Y) mDirection = new Point(0, 1);
+ else mDirection = new Point(0, -1);
+ }
+ } else {
+ if (mBody[0].Y == mFood.Y) {
+ if (mBody[0].X < mFood.X) mDirection = new Point(1, 0);
+ else mDirection = new Point(-1, 0);
+ }
+ }
+ }
+ }
+
+ private void ExtendSnake()
+ {
+ Point[] newBody = new Point[mBody.Length + 1];
+ newBody[0] = mBody[0];
+ Array.Copy(mBody, 0, newBody, 1, mBody.Length);
+ mBody = newBody;
+ }
+
+ private void PlaceFood()
+ {
+ List possiblePlaces = new List();
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ if (!mBody.Contains(new Point(x, y)))
+ possiblePlaces.Add(new Point(x, y));
+
+ int index = mRandom.Next(possiblePlaces.Count);
+ mFood = possiblePlaces[index];
+ }
+
+ private bool InBounds(Point p)
+ {
+ return (p.X >= 0 && p.Y >= 0 && p.X < 8 && p.Y < 8);
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/ToggleGrid.cs b/launchpad-master/IntelOrca.LaunchpadTests/ToggleGrid.cs
new file mode 100644
index 0000000..b84ce49
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/ToggleGrid.cs
@@ -0,0 +1,60 @@
+using IntelOrca.Launchpad;
+
+namespace IntelOrca.LaunchpadTests
+{
+ class ToggleGrid
+ {
+ private LaunchpadDevice mLaunchpadDevice;
+
+ public ToggleGrid(LaunchpadDevice device)
+ {
+ mLaunchpadDevice = device;
+
+ mLaunchpadDevice.DoubleBuffered = false;
+ mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
+
+ mLaunchpadDevice.GetButton(ToolbarButton.Session).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+
+
+ for (int y = 0; y < 4; y++) {
+ for (int x = 0; x < 4; x++) {
+ mLaunchpadDevice[x, y].SetBrightness((ButtonBrightness)x, (ButtonBrightness)y);
+ }
+ }
+
+ }
+
+ private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e)
+ {
+ if (e.Type == ButtonType.Grid) {
+ LaunchpadButton button = mLaunchpadDevice[e.X, e.Y];
+ if (button.RedBrightness == ButtonBrightness.Off && button.GreenBrightness == ButtonBrightness.Off)
+ button.SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+ else
+ button.SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+
+ /*
+ if (button.RedBrightness == ButtonBrightness.Off && button.GreenBrightness == ButtonBrightness.Off)
+ button.SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
+ else if (button.RedBrightness == ButtonBrightness.Full && button.GreenBrightness == ButtonBrightness.Off)
+ button.SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full);
+ else if (button.RedBrightness == ButtonBrightness.Off && button.GreenBrightness == ButtonBrightness.Full)
+ button.SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
+ else
+ button.SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off);
+ */
+ } else if (e.Type == ButtonType.Toolbar) {
+ if (e.ToolbarButton == ToolbarButton.Session) {
+ for (int y = 0; y < 8; y++)
+ for (int x = 0; x < 8; x++)
+ mLaunchpadDevice[x, y].TurnOffLight();
+ }
+ }
+ }
+
+ public void Run()
+ {
+ while (true) ;
+ }
+ }
+}
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/packages.config b/launchpad-master/IntelOrca.LaunchpadTests/packages.config
new file mode 100644
index 0000000..32a593b
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/launchpad-master/IntelOrca.LaunchpadTests/text.txt b/launchpad-master/IntelOrca.LaunchpadTests/text.txt
new file mode 100644
index 0000000..3dee2bc
--- /dev/null
+++ b/launchpad-master/IntelOrca.LaunchpadTests/text.txt
@@ -0,0 +1,293 @@
+!
+X
+X
+X
+
+X
+
+"
+X X
+X X
+
+
+
+
+#
+ X X
+XXXXX
+ X X
+XXXXX
+ X X
+
+'
+X
+X
+
+
+
+
+,
+
+
+
+X
+X
+
+.
+
+
+
+
+X
+
+0
+ XX
+X X
+X X
+X X
+ XX
+
+1
+X
+X
+X
+X
+X
+
+2
+XXX
+ X
+ X
+ X
+XXXX
+
+3
+XXX
+ X
+ XX
+ X
+XXX
+
+4
+ X
+ XX
+ X X
+XXXXX
+ X
+
+5
+XXXX
+X
+XXX
+ X
+XXX
+
+6
+ XX
+X
+XXX
+X X
+ XX
+
+7
+XXXX
+ X
+ X
+ X
+X
+
+8
+XXXX
+X X
+XXXX
+X X
+XXXX
+
+9
+ XX
+X X
+ XXX
+ X
+ XX
+
+A
+XXXX
+X X
+XXXX
+X X
+X X
+
+B
+XXX
+X X
+XXXX
+X X
+XXX
+
+C
+ XXX
+X
+X
+X
+ XXX
+
+D
+XXX
+X X
+X X
+X X
+XXX
+
+E
+XXXX
+X
+XXX
+X
+XXXX
+
+F
+XXXX
+X
+XXX
+X
+X
+
+G
+ XXX
+X
+X XX
+X X
+ XXX
+
+H
+X X
+X X
+XXXX
+X X
+X X
+
+I
+X
+X
+X
+X
+X
+
+J
+XXXX
+ X
+ X
+ X
+XXX
+
+K
+X X
+X X
+XX
+X X
+X X
+
+L
+X
+X
+X
+X
+XXXX
+
+M
+X X
+XX XX
+X X X
+X X
+X X
+
+N
+X X
+XX X
+X X X
+X XX
+X X
+
+O
+ XXX
+X X
+X X
+X X
+ XXX
+
+P
+XXX
+X X
+XXX
+X
+X
+
+Q
+ XX
+X X
+X X
+ XX
+ XX
+
+R
+XXX
+X X
+XXX
+X X
+X X
+
+S
+ XXX
+X
+ XX
+ X
+XXX
+
+T
+XXXXX
+ X
+ X
+ X
+ X
+
+U
+X X
+X X
+X X
+X X
+ XXX
+
+V
+X X
+X X
+ X X
+ X X
+ X
+
+W
+X X
+X X
+X X
+X X X
+ X X
+
+X
+X X
+ X X
+ X
+ X X
+X X
+
+Y
+X X
+ X X
+ X
+ X
+ X
+
+Z
+XXXXX
+ X
+ X
+ X
+XXXXX
\ No newline at end of file
diff --git a/launchpad-master/launchpad-master.zip b/launchpad-master/launchpad-master.zip
new file mode 100644
index 0000000..2a29c4c
Binary files /dev/null and b/launchpad-master/launchpad-master.zip differ
diff --git a/launchpad-master/readme.md b/launchpad-master/readme.md
new file mode 100644
index 0000000..a8205b4
--- /dev/null
+++ b/launchpad-master/readme.md
@@ -0,0 +1,8 @@
+IntelOrca.Launchpad
+=====================
+A .NET framework library written in C# for utilising the Novation Launchpad
+using MidiDotNet. Also includes various cool demos such as the rain sequencer.
+
+Demonstration
+-----------------------
+http://www.youtube.com/watch?v=leYmmiVL1nU
\ No newline at end of file