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