diff --git a/Arduino/LED_Matrix.ino b/Arduino/LED_Matrix.ino new file mode 100644 index 0000000..981679c --- /dev/null +++ b/Arduino/LED_Matrix.ino @@ -0,0 +1,213 @@ +#include "Arduino.h" +#include "FastLED.h" + +#define LED_TYPE WS2812B +#define DATA_PIN 6 + +#define MATRIX_MAX_WIDTH 20 +#define MATRIX_MAX_HEIGHT 20 +#define MATRIX_LED_MAX_COUNT (MATRIX_MAX_WIDTH * MATRIX_MAX_HEIGHT) + +#define STD_WIDTH 10 +#define STD_HEIGHT 10 +#define STD_LED_MAX_COUNT (STD_WIDTH * STD_HEIGHT) + +//#define DEBUG_PRINT_CALLBACK + +#define WAIT while(!Serial.available()); + +uint8_t opcode = 99; + +uint8_t width = STD_WIDTH; +uint8_t height = STD_HEIGHT; + +uint32_t ledCount; + +uint8_t gamma8(uint8_t x) { + uint32_t x2 = (uint32_t) x; + + x2 = x2 * x2 * 258 >> 16; + + return (uint8_t) x2; +} + +CRGB leds[MATRIX_LED_MAX_COUNT]; + +typedef void (*FNPTR_t)(); + +uint8_t getByte() { + WAIT + return Serial.read(); +} + +uint16_t getWord() { + uint16_t highByte = getByte(); + uint16_t lowByte = getByte(); + + return highByte << 8 | lowByte; +} + +void scale() { +#ifdef DEBUG_PRINT_CALLBACK + Serial.println("scale called"); +#endif + width = getByte(); + height = getByte(); + +#ifdef DEBUG_PRINT_CALLBACK + Serial.print("Width: "); + Serial.println(width); + + Serial.print("Height: "); + Serial.println(height); +#endif + + uint16_t newLedCount = width * height; + + if (newLedCount <= MATRIX_LED_MAX_COUNT) { + ledCount = newLedCount; + } else { + return; + } + +#ifdef DEBUG_PRINT_CALLBACK + Serial.print("LEDs: "); + Serial.println(ledCount); +#endif + + + FastLED.addLeds(leds, ledCount); + + for (uint16_t x = 0; x < ledCount; x++) { + leds[x].r = 0; + leds[x].g = 0; + leds[x].b = 0; + } + + FastLED.show(); +} + +void single() { +#ifdef DEBUG_PRINT_CALLBACK + Serial.println("Single called"); +#endif + uint16_t index = getWord(); + + uint8_t green = gamma8(getByte()); + uint8_t red = gamma8(getByte()); + uint8_t blue = gamma8(getByte()); + +#ifdef DEBUG_PRINT_CALLBACK + Serial.print("Index: "); + Serial.println(index); + + Serial.print("Red: "); + Serial.println(red); + + Serial.print("Green: "); + Serial.println(green); + + Serial.print("Blue: "); + Serial.println(blue); +#endif + + leds[index] = CRGB(red, green, blue); + + FastLED.show(); +} + +void image() { + + Serial.readBytes((char*) leds, ledCount * 3); + + for (uint16_t x = 0; x < ledCount; x++) { + leds[x].r = gamma8(leds[x].r); + leds[x].g = gamma8(leds[x].g); + leds[x].b = gamma8(leds[x].b); + } + + FastLED.show(); +} + +void fill() { +#ifdef DEBUG_PRINT_CALLBACK + Serial.println("Called fill"); +#endif + + uint8_t green = gamma8(getByte()); + uint8_t red = gamma8(getByte()); + uint8_t blue = gamma8(getByte()); + +#ifdef DEBUG_PRINT_CALLBACK + Serial.print("Red: "); + Serial.println(red); + + Serial.print("Green: "); + Serial.println(green); + + Serial.print("Blue: "); + Serial.println(blue); +#endif + + for (uint16_t x = 0; x < ledCount; x++) { + leds[x].r = red; + leds[x].g = green; + leds[x].b = blue; + } + + FastLED.show(); +} + +void config() { + Serial.write(width); + Serial.write(height); + + for (uint32_t i = 0; i < ledCount; i++){ + + Serial.write((uint8_t) leds[i].r); + Serial.write((uint8_t) leds[i].g); + Serial.write((uint8_t) leds[i].b); + } +} + +FNPTR_t opcodeTable[] = { + scale, // opcode 0x00 + single, // opcode 0x01 + image, // opcode 0x02 + fill, // opcode 0x03 + config // opcode 0x04 + }; + +void setup() { + ledCount = STD_LED_MAX_COUNT; + + Serial.begin(9600); + + FastLED.addLeds(leds, ledCount); + for (uint16_t i = 0; i < ledCount; i++) { + leds[i].r = 0; + leds[i].g = 0; + leds[i].b = 0; + } + FastLED.show(); +} + +void loop() { + if (Serial.available()) { +#ifdef DEBUG_PRINT_CALLBACK + Serial.println("Opcode read in"); +#endif + + opcode = getByte(); + +#ifdef DEBUG_PRINT_CALLBACK + Serial.print("Opcode changed to:"); + Serial.println(opcode); +#endif + + if (opcode <= 4) { + opcodeTable[opcode](); + Serial.write(21); + } + } +} diff --git a/Matrix App/Matrix App.csproj b/Matrix App/Matrix App.csproj index 4f76f74..20e9fde 100644 --- a/Matrix App/Matrix App.csproj +++ b/Matrix App/Matrix App.csproj @@ -37,6 +37,6 @@ - + \ No newline at end of file diff --git a/Matrix App/MatrixDesigner.cs b/Matrix App/MatrixDesigner.cs index 4b3d9a6..e708807 100644 --- a/Matrix App/MatrixDesigner.cs +++ b/Matrix App/MatrixDesigner.cs @@ -63,7 +63,7 @@ namespace Matrix_App // apply light-mode by default new LightMode().ApplyTheme(this); } - + private void Init() { // Create port name update timer @@ -99,7 +99,7 @@ namespace Matrix_App if (((int) DateTime.Now.DayOfWeek) != 3) return; - if (new Random().Next(0, 9) <= 1) + if (new Random().Next(0, 9) >= 1) return; using (Bitmap wednesdayFrog = new Bitmap(Properties.Resources.Frosch)) @@ -646,7 +646,7 @@ namespace Matrix_App { if (Timeline.InvokeRequired) { - // invoke on the comboboxes thread + // invoke on the combo-boxes thread Timeline.Invoke(new Action(() => { if (Timeline.Value < Timeline.Maximum) diff --git a/Matrix App/MatrixGifGenerator.cs b/Matrix App/MatrixGifGenerator.cs index 3eccf01..ed4d72c 100644 --- a/Matrix App/MatrixGifGenerator.cs +++ b/Matrix App/MatrixGifGenerator.cs @@ -1,5 +1,6 @@ using Matrix_App.PregeneratedMods; using System; +using System.Diagnostics; using System.Drawing; using System.Reflection; using System.Text.RegularExpressions; @@ -85,8 +86,8 @@ namespace Matrix_App }; button.Click += (sender, e) => OpenGeneratorUi(generator, matrix); button.Image = CreateSnapshot(generator); - button.TextImageRelation = TextImageRelation.ImageAboveText; - button.Height = FilterPreviewHeight * 2; + button.TextImageRelation = TextImageRelation.ImageBeforeText; + button.Height = FilterPreviewHeight * 3 / 2; anchor.Controls.Add(button); } @@ -179,7 +180,7 @@ namespace Matrix_App PlaybackTimer.Interval = _form.GetDelayTime(); PlaybackTimer.Enabled = true; - CreateDivider(controlPanel); + CreateDivider(controlPanel, 2); foreach (var field in fields) { if (field.IsStatic || !field.IsPublic) @@ -187,23 +188,11 @@ namespace Matrix_App var fieldValue = field.GetValue(_generator); - controlPanel.Controls.Add(GetFieldUi(field, fieldValue, _generator)); - } - - if (controlPanel.Controls.Count > 1) - { - CreateDivider(controlPanel); - - var label = new Label() { Text = "Settings" }; - label.Font = new Font(label.Font, FontStyle.Bold); - controlPanel.Controls.Add(label); + controlPanel.Controls.AddRange(GetFieldUi(field, _generator.GetType(), fieldValue, _generator)); + CreateDivider(controlPanel, 1); } controlPanel.Controls.Add(_preview); - CreateDivider(controlPanel); - var playLabel = new Label() { Text = "Playback preview" }; - playLabel.Font = new Font(playLabel.Font, FontStyle.Bold); - controlPanel.Controls.Add(playLabel); FlowLayoutPanel southPane = new FlowLayoutPanel { @@ -229,7 +218,7 @@ namespace Matrix_App return success; } - private static Control GetFieldUi(FieldInfo field, object? fieldValue, MatrixGifGenerator generator) + private static Control[] GetFieldUi(FieldInfo field, Type clazz, object? fieldValue, MatrixGifGenerator generator) { var panel = new FlowLayoutPanel { @@ -237,11 +226,24 @@ namespace Matrix_App Anchor = AnchorStyles.Top | AnchorStyles.Left, AutoSize = true }; + + var title = GetBetterFieldName(field.Name); + var description = new Label(); + + if (Attribute.GetCustomAttribute(field, typeof(UiDescriptionAttribute)) is UiDescriptionAttribute desc) + { + title = desc.title; + description.Text = desc.description; + description.ForeColor = Color.Gray; + description.Height += 10; + description.AutoSize = true; + } + panel.Controls.Add(new Label { - TextAlign = System.Drawing.ContentAlignment.MiddleLeft, - Text = GetBetterFieldName(field.Name), + TextAlign = ContentAlignment.MiddleLeft, + Text = title, Dock = DockStyle.Left, Anchor = AnchorStyles.Top | AnchorStyles.Left, Width = 100 @@ -305,7 +307,7 @@ namespace Matrix_App } } - return panel; + return new Control[] {description, panel}; } /// @@ -354,13 +356,13 @@ namespace Matrix_App /// Adds a separating line to the controls /// /// - private static void CreateDivider(Control controlPanel) + private static void CreateDivider(Control controlPanel, int height) { var divider = new Label { BorderStyle = BorderStyle.Fixed3D, AutoSize = false, - Height = 2, + Height = height, Width = 500 }; diff --git a/Matrix App/PregeneratedMods/Boxblur.cs b/Matrix App/PregeneratedMods/Boxblur.cs index 9b4a428..503b8a5 100644 --- a/Matrix App/PregeneratedMods/Boxblur.cs +++ b/Matrix App/PregeneratedMods/Boxblur.cs @@ -1,12 +1,11 @@ using System; -using System.Collections.Generic; -using System.Text; using static Matrix_App.GifGeneratorUtils; namespace Matrix_App.PregeneratedMods { - public class Boxblur : MatrixGifGenerator + public sealed class Boxblur : MatrixGifGenerator { + [UiDescriptionAttribute(title: "Blur size", description: "The side length of the bounding square used to blur in pixels")] public int blurSize = 2; protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b) diff --git a/Matrix App/PregeneratedMods/ColorAdjust.cs b/Matrix App/PregeneratedMods/ColorAdjust.cs index 2e35d3a..3a6599e 100644 --- a/Matrix App/PregeneratedMods/ColorAdjust.cs +++ b/Matrix App/PregeneratedMods/ColorAdjust.cs @@ -7,12 +7,18 @@ namespace Matrix_App.PregeneratedMods { public sealed class ColorAdjust : MatrixGifGenerator { + [UiDescriptionAttribute(title: "Tone offset", description: "Sets an additional offset to the pixels hue")] public float hueOffset = 0.0f; + [UiDescriptionAttribute(title: "Saturation boost", description: "Decreases or increases saturation")] public float saturationBoost = 0.5f; + [UiDescriptionAttribute(title: "Brightness boost", description: "Decreases or increases brightness")] public float valueBoost = 0.5f; + [UiDescriptionAttribute(title: "Red boost", description: "Decreases or increases Red")] public float redBoost = 0.5f; + [UiDescriptionAttribute(title: "Green boost", description: "Decreases or increases Green")] public float greenBoost = 0.5f; + [UiDescriptionAttribute(title: "Blue boost", description: "Decreases or increases Blue")] public float blueBoost = 0.5f; private float boost(float x, float y) diff --git a/Matrix App/PregeneratedMods/Grayscale.cs b/Matrix App/PregeneratedMods/Grayscale.cs index a026e85..df83745 100644 --- a/Matrix App/PregeneratedMods/Grayscale.cs +++ b/Matrix App/PregeneratedMods/Grayscale.cs @@ -7,6 +7,7 @@ namespace Matrix_App.PregeneratedMods { public sealed class Grayscale : MatrixGifGenerator { + [UiDescriptionAttribute(title: "use Luminance", description: "Use luminance as defined by ITU-R BT.709 as grayscale output")] public bool byLuminance = false; protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b) diff --git a/Matrix App/PregeneratedMods/RandomPixels.cs b/Matrix App/PregeneratedMods/RandomPixels.cs index 6793b80..33c6e58 100644 --- a/Matrix App/PregeneratedMods/RandomPixels.cs +++ b/Matrix App/PregeneratedMods/RandomPixels.cs @@ -4,6 +4,7 @@ namespace Matrix_App.PregeneratedMods { public class RandomPixels : MatrixGifGenerator { + [UiDescriptionAttribute(title: "Seed", description: "Just a seed for a bad deterministic random function")] public int seed = 0; protected override void ColorFragment(in int x, in int y, in float u, in float v, in int frame, out float r, out float g, out float b) diff --git a/Matrix App/PregeneratedMods/SimpleRainbow.cs b/Matrix App/PregeneratedMods/SimpleRainbow.cs index 3136d0e..926c341 100644 --- a/Matrix App/PregeneratedMods/SimpleRainbow.cs +++ b/Matrix App/PregeneratedMods/SimpleRainbow.cs @@ -1,17 +1,18 @@ using System; -using System.Collections.Generic; -using System.Text; - using static Matrix_App.GifGeneratorUtils; -namespace Matrix_App +namespace Matrix_App.PregeneratedMods { public class SimpleRainbow : MatrixGifGenerator { + [UiDescription(title: "Radial", description: "Uses the angle to alter hues")] public bool radial = false; + [UiDescription(title: "Saturation", description: "Overall saturation")] public float saturation = 1.0f; + [UiDescription(title: "Brightness", description: "Overall brightness")] public float value = 1.0f; + [UiDescription(title: "Hue rotation", description: "Offset for hue calculation")] public float rotation = 0.0f; protected override void ColorFragment(in int x, in int y, diff --git a/Matrix App/PregeneratedMods/UIDescriptionAttribute.cs b/Matrix App/PregeneratedMods/UIDescriptionAttribute.cs new file mode 100644 index 0000000..0d7fb06 --- /dev/null +++ b/Matrix App/PregeneratedMods/UIDescriptionAttribute.cs @@ -0,0 +1,17 @@ +using System; + +namespace Matrix_App.PregeneratedMods +{ + [AttributeUsage(AttributeTargets.Field)] + public class UiDescriptionAttribute : Attribute + { + public string title; + public string description; + + public UiDescriptionAttribute(string title, string description) + { + this.title = title; + this.description = description; + } + } +} \ No newline at end of file diff --git a/Matrix App/Program.cs b/Matrix App/Program.cs index f41a2db..251cd1e 100644 --- a/Matrix App/Program.cs +++ b/Matrix App/Program.cs @@ -10,17 +10,22 @@ namespace Matrix_App /// [STAThread] private static void Main() - { - SplashScreen.ShowSplashScreen(); - + { Application.SetHighDpiMode(HighDpiMode.SystemAware); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); + SplashScreen.ShowSplashScreen(); + var designer = new MatrixDesignerMain(); SplashScreen.CloseForm(); + designer.StartPosition = FormStartPosition.CenterScreen; + designer.WindowState = FormWindowState.Minimized; + designer.Show(); + designer.WindowState = FormWindowState.Normal; + Application.Run(designer); } } diff --git a/Matrix App/Resources/pfüsikuh.png b/Matrix App/Resources/pfüsikuh.png index 690d786..bd297f2 100644 Binary files a/Matrix App/Resources/pfüsikuh.png and b/Matrix App/Resources/pfüsikuh.png differ diff --git a/Matrix App/SplashScreen.cs b/Matrix App/SplashScreen.cs index 6d967b4..b35dba3 100644 --- a/Matrix App/SplashScreen.cs +++ b/Matrix App/SplashScreen.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.Drawing; +using System.Threading; using System.Windows.Forms; namespace Matrix_App @@ -17,8 +18,12 @@ namespace Matrix_App Controls.Add(new Label() { - Image = Properties.Resources.Pfüsikuh + Image = Properties.Resources.Pfüsikuh, + Size = new Size(Properties.Resources.Pfüsikuh.Width, Properties.Resources.Pfüsikuh.Height) }); + + Size = new Size(Properties.Resources.Pfüsikuh.Width, Properties.Resources.Pfüsikuh.Height); + StartPosition = FormStartPosition.CenterScreen; } public static void ShowSplashScreen() diff --git a/Matrix App/bin/Debug/netcoreapp3.1/Matrix App.dll b/Matrix App/bin/Debug/netcoreapp3.1/Matrix App.dll index e23d833..e55c3a3 100644 Binary files a/Matrix App/bin/Debug/netcoreapp3.1/Matrix App.dll and b/Matrix App/bin/Debug/netcoreapp3.1/Matrix App.dll differ diff --git a/Matrix App/bin/Debug/netcoreapp3.1/Matrix App.pdb b/Matrix App/bin/Debug/netcoreapp3.1/Matrix App.pdb index e9c8d6b..bf8aba4 100644 Binary files a/Matrix App/bin/Debug/netcoreapp3.1/Matrix App.pdb and b/Matrix App/bin/Debug/netcoreapp3.1/Matrix App.pdb differ diff --git a/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.csproj.CoreCompileInputs.cache b/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.csproj.CoreCompileInputs.cache index 75a64fd..5c4c3e9 100644 --- a/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.csproj.CoreCompileInputs.cache +++ b/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -ee8b86baf58d13435f960406ec4b0be78d0cc26c +0e5f843b45897d8b4a3e6250399d748fbf87d606 diff --git a/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.csproj.GenerateResource.cache b/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.csproj.GenerateResource.cache index 42e045b..144f2a0 100644 Binary files a/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.csproj.GenerateResource.cache and b/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.csproj.GenerateResource.cache differ diff --git a/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.dll b/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.dll index e23d833..e55c3a3 100644 Binary files a/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.dll and b/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.dll differ diff --git a/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.pdb b/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.pdb index e9c8d6b..bf8aba4 100644 Binary files a/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.pdb and b/Matrix App/obj/Debug/netcoreapp3.1/Matrix App.pdb differ diff --git a/Matrix App/obj/Debug/netcoreapp3.1/Matrix_App.Properties.Resources.resources b/Matrix App/obj/Debug/netcoreapp3.1/Matrix_App.Properties.Resources.resources index 54dc4a6..ba39fa7 100644 Binary files a/Matrix App/obj/Debug/netcoreapp3.1/Matrix_App.Properties.Resources.resources and b/Matrix App/obj/Debug/netcoreapp3.1/Matrix_App.Properties.Resources.resources differ