New Release Build 3.5.6-RC5
This commit is contained in:
parent
0297d922ab
commit
5a9fb1e9c9
|
@ -1,11 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Matrix_App
|
||||
{
|
||||
|
@ -15,44 +11,45 @@ namespace Matrix_App
|
|||
public class GifWriter : IDisposable
|
||||
{
|
||||
#region Fields
|
||||
const long SourceGlobalColorInfoPosition = 10,
|
||||
SourceImageBlockPosition = 789;
|
||||
|
||||
private const long SourceGlobalColorInfoPosition = 10, SourceImageBlockPosition = 789;
|
||||
|
||||
readonly BinaryWriter _writer;
|
||||
bool _firstFrame = true;
|
||||
readonly object _syncLock = new object();
|
||||
private readonly object syncLock = new object();
|
||||
private readonly BinaryWriter writer;
|
||||
private bool firstFrame = true;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of GifWriter.
|
||||
/// </summary>
|
||||
/// <param name="OutStream">The <see cref="Stream"/> to output the Gif to.</param>
|
||||
/// <param name="DefaultFrameDelay">Default Delay between consecutive frames... FrameRate = 1000 / DefaultFrameDelay.</param>
|
||||
/// <param name="Repeat">No of times the Gif should repeat... -1 not to repeat, 0 to repeat indefinitely.</param>
|
||||
public GifWriter(Stream OutStream, int DefaultFrameDelay = 500, int Repeat = 0)
|
||||
/// <param name="outStream">The <see cref="Stream"/> to output the Gif to.</param>
|
||||
/// <param name="defaultFrameDelay">Default Delay between consecutive frames... FrameRate = 1000 / DefaultFrameDelay.</param>
|
||||
/// <param name="repeat">No of times the Gif should repeat... -1 not to repeat, 0 to repeat indefinitely.</param>
|
||||
public GifWriter(Stream outStream, int defaultFrameDelay = 500, int repeat = 0)
|
||||
{
|
||||
if (OutStream == null)
|
||||
throw new ArgumentNullException(nameof(OutStream));
|
||||
if (outStream == null)
|
||||
throw new ArgumentNullException(nameof(outStream));
|
||||
|
||||
if (DefaultFrameDelay <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(DefaultFrameDelay));
|
||||
if (defaultFrameDelay <= 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(defaultFrameDelay));
|
||||
|
||||
if (Repeat < -1)
|
||||
throw new ArgumentOutOfRangeException(nameof(Repeat));
|
||||
if (repeat < -1)
|
||||
throw new ArgumentOutOfRangeException(nameof(repeat));
|
||||
|
||||
_writer = new BinaryWriter(OutStream);
|
||||
this.DefaultFrameDelay = DefaultFrameDelay;
|
||||
this.Repeat = Repeat;
|
||||
writer = new BinaryWriter(outStream);
|
||||
this.DefaultFrameDelay = defaultFrameDelay;
|
||||
this.Repeat = repeat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of GifWriter.
|
||||
/// </summary>
|
||||
/// <param name="FileName">The path to the file to output the Gif to.</param>
|
||||
/// <param name="DefaultFrameDelay">Default Delay between consecutive frames... FrameRate = 1000 / DefaultFrameDelay.</param>
|
||||
/// <param name="Repeat">No of times the Gif should repeat... -1 not to repeat, 0 to repeat indefinitely.</param>
|
||||
public GifWriter(string FileName, int DefaultFrameDelay = 500, int Repeat = -1)
|
||||
: this(new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read), DefaultFrameDelay, Repeat) { }
|
||||
/// <param name="fileName">The path to the file to output the Gif to.</param>
|
||||
/// <param name="defaultFrameDelay">Default Delay between consecutive frames... FrameRate = 1000 / DefaultFrameDelay.</param>
|
||||
/// <param name="repeat">No of times the Gif should repeat... -1 not to repeat, 0 to repeat indefinitely.</param>
|
||||
public GifWriter(string fileName, int defaultFrameDelay = 500, int repeat = -1)
|
||||
: this(new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read), defaultFrameDelay, repeat) { }
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
|
@ -80,114 +77,114 @@ namespace Matrix_App
|
|||
/// <summary>
|
||||
/// Adds a frame to this animation.
|
||||
/// </summary>
|
||||
/// <param name="Image">The image to add</param>
|
||||
/// <param name="Delay">Delay in Milliseconds between this and last frame... 0 = <see cref="DefaultFrameDelay"/></param>
|
||||
public void WriteFrame(Image Image, int Delay = 0)
|
||||
/// <param name="image">The image to add</param>
|
||||
/// <param name="delay">Delay in Milliseconds between this and last frame... 0 = <see cref="DefaultFrameDelay"/></param>
|
||||
public void WriteFrame(Image image, int delay = 0)
|
||||
{
|
||||
lock (_syncLock)
|
||||
lock (syncLock)
|
||||
using (var gifStream = new MemoryStream())
|
||||
{
|
||||
Image.Save(gifStream, ImageFormat.Gif);
|
||||
image.Save(gifStream, ImageFormat.Gif);
|
||||
|
||||
// Steal the global color table info
|
||||
if (_firstFrame)
|
||||
InitHeader(gifStream, _writer, Image.Width, Image.Height);
|
||||
if (firstFrame)
|
||||
InitHeader(gifStream, writer, image.Width, image.Height);
|
||||
|
||||
WriteGraphicControlBlock(gifStream, _writer, Delay == 0 ? DefaultFrameDelay : Delay);
|
||||
WriteImageBlock(gifStream, _writer, !_firstFrame, 0, 0, Image.Width, Image.Height);
|
||||
WriteGraphicControlBlock(gifStream, writer, delay == 0 ? DefaultFrameDelay : delay);
|
||||
WriteImageBlock(gifStream, writer, !firstFrame, 0, 0, image.Width, image.Height);
|
||||
}
|
||||
|
||||
if (_firstFrame)
|
||||
_firstFrame = false;
|
||||
if (firstFrame)
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
#region Write
|
||||
void InitHeader(Stream SourceGif, BinaryWriter Writer, int Width, int Height)
|
||||
private void InitHeader(Stream sourceGif, BinaryWriter writer, int width, int height)
|
||||
{
|
||||
// File Header
|
||||
Writer.Write("GIF".ToCharArray()); // File type
|
||||
Writer.Write("89a".ToCharArray()); // File Version
|
||||
writer.Write("GIF".ToCharArray()); // File type
|
||||
writer.Write("89a".ToCharArray()); // File Version
|
||||
|
||||
Writer.Write((short)(DefaultWidth == 0 ? Width : DefaultWidth)); // Initial Logical Width
|
||||
Writer.Write((short)(DefaultHeight == 0 ? Height : DefaultHeight)); // Initial Logical Height
|
||||
writer.Write((short)(DefaultWidth == 0 ? width : DefaultWidth)); // Initial Logical Width
|
||||
writer.Write((short)(DefaultHeight == 0 ? height : DefaultHeight)); // Initial Logical Height
|
||||
|
||||
SourceGif.Position = SourceGlobalColorInfoPosition;
|
||||
Writer.Write((byte)SourceGif.ReadByte()); // Global Color Table Info
|
||||
Writer.Write((byte)0); // Background Color Index
|
||||
Writer.Write((byte)0); // Pixel aspect ratio
|
||||
WriteColorTable(SourceGif, Writer);
|
||||
sourceGif.Position = SourceGlobalColorInfoPosition;
|
||||
writer.Write((byte)sourceGif.ReadByte()); // Global Color Table Info
|
||||
writer.Write((byte)0); // Background Color Index
|
||||
writer.Write((byte)0); // Pixel aspect ratio
|
||||
WriteColorTable(sourceGif, writer);
|
||||
|
||||
// App Extension Header for Repeating
|
||||
if (Repeat == -1)
|
||||
return;
|
||||
|
||||
Writer.Write(unchecked((short)0xff21)); // Application Extension Block Identifier
|
||||
Writer.Write((byte)0x0b); // Application Block Size
|
||||
Writer.Write("NETSCAPE2.0".ToCharArray()); // Application Identifier
|
||||
Writer.Write((byte)3); // Application block length
|
||||
Writer.Write((byte)1);
|
||||
Writer.Write((short)Repeat); // Repeat count for images.
|
||||
Writer.Write((byte)0); // terminator
|
||||
writer.Write(unchecked((short)0xff21)); // Application Extension Block Identifier
|
||||
writer.Write((byte)0x0b); // Application Block Size
|
||||
writer.Write("NETSCAPE2.0".ToCharArray()); // Application Identifier
|
||||
writer.Write((byte)3); // Application block length
|
||||
writer.Write((byte)1);
|
||||
writer.Write((short)Repeat); // Repeat count for images.
|
||||
writer.Write((byte)0); // terminator
|
||||
}
|
||||
|
||||
static void WriteColorTable(Stream SourceGif, BinaryWriter Writer)
|
||||
static void WriteColorTable(Stream sourceGif, BinaryWriter writer)
|
||||
{
|
||||
SourceGif.Position = 13; // Locating the image color table
|
||||
sourceGif.Position = 13; // Locating the image color table
|
||||
var colorTable = new byte[768];
|
||||
SourceGif.Read(colorTable, 0, colorTable.Length);
|
||||
Writer.Write(colorTable, 0, colorTable.Length);
|
||||
sourceGif.Read(colorTable, 0, colorTable.Length);
|
||||
writer.Write(colorTable, 0, colorTable.Length);
|
||||
}
|
||||
|
||||
static void WriteGraphicControlBlock(Stream SourceGif, BinaryWriter Writer, int FrameDelay)
|
||||
static void WriteGraphicControlBlock(Stream sourceGif, BinaryWriter writer, int frameDelay)
|
||||
{
|
||||
SourceGif.Position = 781; // Locating the source GCE
|
||||
sourceGif.Position = 781; // Locating the source GCE
|
||||
var blockhead = new byte[8];
|
||||
SourceGif.Read(blockhead, 0, blockhead.Length); // Reading source GCE
|
||||
sourceGif.Read(blockhead, 0, blockhead.Length); // Reading source GCE
|
||||
|
||||
Writer.Write(unchecked((short)0xf921)); // Identifier
|
||||
Writer.Write((byte)0x04); // Block Size
|
||||
Writer.Write((byte)(blockhead[3] & 0xf7 | 0x08)); // Setting disposal flag
|
||||
Writer.Write((short)(FrameDelay / 10)); // Setting frame delay
|
||||
Writer.Write(blockhead[6]); // Transparent color index
|
||||
Writer.Write((byte)0); // Terminator
|
||||
writer.Write(unchecked((short)0xf921)); // Identifier
|
||||
writer.Write((byte)0x04); // Block Size
|
||||
writer.Write((byte)(blockhead[3] & 0xf7 | 0x08)); // Setting disposal flag
|
||||
writer.Write((short)(frameDelay / 10)); // Setting frame delay
|
||||
writer.Write(blockhead[6]); // Transparent color index
|
||||
writer.Write((byte)0); // Terminator
|
||||
}
|
||||
|
||||
static void WriteImageBlock(Stream SourceGif, BinaryWriter Writer, bool IncludeColorTable, int X, int Y, int Width, int Height)
|
||||
static void WriteImageBlock(Stream sourceGif, BinaryWriter writer, bool includeColorTable, int x, int y, int width, int height)
|
||||
{
|
||||
SourceGif.Position = SourceImageBlockPosition; // Locating the image block
|
||||
sourceGif.Position = SourceImageBlockPosition; // Locating the image block
|
||||
var header = new byte[11];
|
||||
SourceGif.Read(header, 0, header.Length);
|
||||
Writer.Write(header[0]); // Separator
|
||||
Writer.Write((short)X); // Position X
|
||||
Writer.Write((short)Y); // Position Y
|
||||
Writer.Write((short)Width); // Width
|
||||
Writer.Write((short)Height); // Height
|
||||
sourceGif.Read(header, 0, header.Length);
|
||||
writer.Write(header[0]); // Separator
|
||||
writer.Write((short)x); // Position X
|
||||
writer.Write((short)y); // Position Y
|
||||
writer.Write((short)width); // Width
|
||||
writer.Write((short)height); // Height
|
||||
|
||||
if (IncludeColorTable) // If first frame, use global color table - else use local
|
||||
if (includeColorTable) // If first frame, use global color table - else use local
|
||||
{
|
||||
SourceGif.Position = SourceGlobalColorInfoPosition;
|
||||
Writer.Write((byte)(SourceGif.ReadByte() & 0x3f | 0x80)); // Enabling local color table
|
||||
WriteColorTable(SourceGif, Writer);
|
||||
sourceGif.Position = SourceGlobalColorInfoPosition;
|
||||
writer.Write((byte)(sourceGif.ReadByte() & 0x3f | 0x80)); // Enabling local color table
|
||||
WriteColorTable(sourceGif, writer);
|
||||
}
|
||||
else Writer.Write((byte)(header[9] & 0x07 | 0x07)); // Disabling local color table
|
||||
else writer.Write((byte)(header[9] & 0x07 | 0x07)); // Disabling local color table
|
||||
|
||||
Writer.Write(header[10]); // LZW Min Code Size
|
||||
writer.Write(header[10]); // LZW Min Code Size
|
||||
|
||||
// Read/Write image data
|
||||
SourceGif.Position = SourceImageBlockPosition + header.Length;
|
||||
sourceGif.Position = SourceImageBlockPosition + header.Length;
|
||||
|
||||
var dataLength = SourceGif.ReadByte();
|
||||
var dataLength = sourceGif.ReadByte();
|
||||
while (dataLength > 0)
|
||||
{
|
||||
var imgData = new byte[dataLength];
|
||||
SourceGif.Read(imgData, 0, dataLength);
|
||||
sourceGif.Read(imgData, 0, dataLength);
|
||||
|
||||
Writer.Write((byte)dataLength);
|
||||
Writer.Write(imgData, 0, dataLength);
|
||||
dataLength = SourceGif.ReadByte();
|
||||
writer.Write((byte)dataLength);
|
||||
writer.Write(imgData, 0, dataLength);
|
||||
dataLength = sourceGif.ReadByte();
|
||||
}
|
||||
|
||||
Writer.Write((byte)0); // Terminator
|
||||
writer.Write((byte)0); // Terminator
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -197,10 +194,10 @@ namespace Matrix_App
|
|||
public void Dispose()
|
||||
{
|
||||
// Complete File
|
||||
_writer.Write((byte)0x3b); // File Trailer
|
||||
writer.Write((byte)0x3b); // File Trailer
|
||||
|
||||
_writer.BaseStream.Dispose();
|
||||
_writer.Dispose();
|
||||
writer.BaseStream.Dispose();
|
||||
writer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,5 +38,6 @@
|
|||
<EmbeddedResource Remove="SplashScreen.resx" />
|
||||
<None Remove="Resources\pfüsikuh.png" />
|
||||
<None Remove="Utils.cs~" />
|
||||
<None Remove="Resources\pfüsikuh.png~" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -10,13 +10,13 @@ namespace Matrix_App
|
|||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
IMAGE_DRAWER.Stop();
|
||||
MatrixGifGenerator.Close();
|
||||
commandQueue.Close();
|
||||
if (disposing && (components != null))
|
||||
|
@ -47,7 +47,6 @@ namespace Matrix_App
|
|||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.FramesLabel = new System.Windows.Forms.Label();
|
||||
this.configButton = new System.Windows.Forms.Button();
|
||||
this.read_me = new System.Windows.Forms.RichTextBox();
|
||||
this.DelayLabel = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
|
@ -81,7 +80,7 @@ namespace Matrix_App
|
|||
this.Play = new System.Windows.Forms.Button();
|
||||
this.Apply = new System.Windows.Forms.Button();
|
||||
this.DragDropButton = new System.Windows.Forms.Button();
|
||||
this.matrixView = new Matrix_App.Matrix();
|
||||
matrixView = new Matrix_App.Matrix();
|
||||
this.panel3 = new System.Windows.Forms.Panel();
|
||||
this.Modus.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
|
@ -140,7 +139,6 @@ namespace Matrix_App
|
|||
this.tabPage1.Controls.Add(this.label3);
|
||||
this.tabPage1.Controls.Add(this.FramesLabel);
|
||||
this.tabPage1.Controls.Add(this.configButton);
|
||||
this.tabPage1.Controls.Add(this.read_me);
|
||||
this.tabPage1.Controls.Add(this.DelayLabel);
|
||||
this.tabPage1.Controls.Add(this.label4);
|
||||
this.tabPage1.Controls.Add(this.label2);
|
||||
|
@ -248,17 +246,6 @@ namespace Matrix_App
|
|||
this.configButton.UseVisualStyleBackColor = true;
|
||||
this.configButton.Click += new System.EventHandler(this.ConfigButton_Click);
|
||||
//
|
||||
// read_me
|
||||
//
|
||||
this.read_me.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.read_me.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.read_me.Location = new System.Drawing.Point(0, 344);
|
||||
this.read_me.Name = "read_me";
|
||||
this.read_me.ReadOnly = true;
|
||||
this.read_me.Size = new System.Drawing.Size(232, 291);
|
||||
this.read_me.TabIndex = 5;
|
||||
this.read_me.Text = "Reads Me";
|
||||
//
|
||||
// DelayLabel
|
||||
//
|
||||
this.DelayLabel.AutoSize = true;
|
||||
|
@ -689,16 +676,16 @@ namespace Matrix_App
|
|||
//
|
||||
// matrixView
|
||||
//
|
||||
this.matrixView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.matrixView.Location = new System.Drawing.Point(16, 16);
|
||||
this.matrixView.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.matrixView.Name = "matrixView";
|
||||
this.matrixView.Size = new System.Drawing.Size(627, 557);
|
||||
this.matrixView.TabIndex = 3;
|
||||
matrixView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
matrixView.Location = new System.Drawing.Point(16, 16);
|
||||
matrixView.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
matrixView.Name = "matrixView";
|
||||
matrixView.Size = new System.Drawing.Size(627, 557);
|
||||
matrixView.TabIndex = 3;
|
||||
//
|
||||
// panel3
|
||||
//
|
||||
this.panel3.Controls.Add(this.matrixView);
|
||||
this.panel3.Controls.Add(matrixView);
|
||||
this.panel3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel3.Location = new System.Drawing.Point(240, 0);
|
||||
this.panel3.Name = "panel3";
|
||||
|
@ -757,7 +744,6 @@ namespace Matrix_App
|
|||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.RichTextBox read_me;
|
||||
private System.Windows.Forms.Panel ToolBar;
|
||||
private System.Windows.Forms.NumericUpDown matrixHeight;
|
||||
private System.Windows.Forms.NumericUpDown matrixWidth;
|
||||
|
@ -782,7 +768,7 @@ namespace Matrix_App
|
|||
private System.Windows.Forms.Button Save;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Button configButton;
|
||||
private Matrix matrixView;
|
||||
private static Matrix matrixView;
|
||||
private System.Windows.Forms.TabPage pregeneratedMods;
|
||||
private System.Windows.Forms.FlowLayoutPanel pregeneratedModsBase;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
@ -44,8 +45,10 @@ namespace Matrix_App
|
|||
/// <summary>
|
||||
/// Gif like frame video buffer
|
||||
/// </summary>
|
||||
public byte[][] gifBuffer = CreateImageRGB_NT(MatrixStartWidth, MatrixStartHeight, MatrixStartFrames);
|
||||
|
||||
public static byte[][] gifBuffer = CreateImageRGB_NT(MatrixStartWidth, MatrixStartHeight, MatrixStartFrames);
|
||||
|
||||
public static readonly ThreadQueue IMAGE_DRAWER = new ThreadQueue("Matrix Image Drawer", 4);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Setup
|
||||
|
@ -595,24 +598,37 @@ namespace Matrix_App
|
|||
|
||||
private void Timeline_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
int width = matrixView.matrixWidth();
|
||||
int height = matrixView.matrixHeight();
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
var timeFrame = Timeline.Value;
|
||||
|
||||
IMAGE_DRAWER.Enqueue(() =>
|
||||
{
|
||||
int index = y * width;
|
||||
WriteImage(gifBuffer[timeFrame]);
|
||||
|
||||
var width = matrixView.matrixWidth();
|
||||
var height = matrixView.matrixHeight();
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
lock (matrixView)
|
||||
{
|
||||
int tmp = (index + x) * 3;
|
||||
for (var y = 0; y < height; y++)
|
||||
{
|
||||
var index = y * width;
|
||||
|
||||
var color = Color.FromArgb(gifBuffer[Timeline.Value][tmp + 1], gifBuffer[Timeline.Value][tmp], gifBuffer[Timeline.Value][tmp + 2]);
|
||||
for (var x = 0; x < width; x++)
|
||||
{
|
||||
var tmp = (index + x) * 3;
|
||||
|
||||
matrixView.SetPixelNoRefresh(x, y, color);
|
||||
var color = Color.FromArgb(gifBuffer[timeFrame][tmp + 1], gifBuffer[timeFrame][tmp], gifBuffer[timeFrame][tmp + 2]);
|
||||
|
||||
matrixView.SetPixelNoRefresh(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matrixView.Refresh();
|
||||
|
||||
return true;
|
||||
});
|
||||
matrixView.Refresh();
|
||||
WriteImage(gifBuffer[Timeline.Value]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
using Matrix_App.PregeneratedMods;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using Matrix_App.PregeneratedMods.reflection;
|
||||
using static Matrix_App.Utils;
|
||||
using static Matrix_App.Defaults;
|
||||
using Timer = System.Windows.Forms.Timer;
|
||||
|
@ -26,33 +25,46 @@ namespace Matrix_App
|
|||
new Grayscale(),
|
||||
new Invert()
|
||||
};
|
||||
|
||||
private static readonly Timer PlaybackTimer = new Timer();
|
||||
|
||||
private static int _playbackFrame;
|
||||
|
||||
protected static int totalFrames;
|
||||
protected static byte[][]? actualStore;
|
||||
|
||||
// Static generator accessible members
|
||||
// must work on multiple threads
|
||||
protected static int totalFrames; // total amount of frames to generate
|
||||
protected static byte[][]? actualStore; // image copy of previous GIF for generator
|
||||
|
||||
protected static int width;
|
||||
protected static int height;
|
||||
|
||||
// updates the preview matrix for animation
|
||||
private static readonly Timer PlaybackTimer = new Timer();
|
||||
// current frame to play
|
||||
private static int _playbackFrame;
|
||||
|
||||
// temporary buffer for storing snapshots for buttons
|
||||
private static readonly byte[][] Snapshot;
|
||||
private static byte[][] _initialBuffer;
|
||||
private static byte[][] _initialBuffer; // temporary buffer for swapping
|
||||
|
||||
// Generator renderer
|
||||
private static readonly ThreadQueue Renderer;
|
||||
|
||||
// Current generator to use
|
||||
private static MatrixGifGenerator? _generator;
|
||||
|
||||
static MatrixGifGenerator()
|
||||
{
|
||||
PlaybackTimer.Tick += PlaybackFrame;
|
||||
|
||||
|
||||
// Generate buffer for button filter snapshots
|
||||
Snapshot = CreateImageRGB_NT(FilterPreviewWidth, FilterPreviewHeight, 1);
|
||||
_initialBuffer = CreateImageRGB_NT(FilterPreviewWidth, FilterPreviewHeight, 1);
|
||||
|
||||
Renderer = new ThreadQueue("Matrix Gif Renderer", 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Plays the next frame of what is currently in the animation buffer
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private static void PlaybackFrame(object? sender, EventArgs e)
|
||||
{
|
||||
if (_playbackFrame >= _animationBuffer.Length - 1)
|
||||
|
@ -65,12 +77,25 @@ namespace Matrix_App
|
|||
_playbackFrame++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Colors a single fragment at the specified pixel location (x|y) at frame frame.
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <param name="u">Normalized pixel X-coordinate</param>
|
||||
/// <param name="v">Normalized pixel Y-coordinate</param>
|
||||
/// <param name="frame">Current frame</param>
|
||||
/// <param name="r">Pixel Red value in range [0, 1] (saturated)</param>
|
||||
/// <param name="g">Pixel Green value in range [0, 1] (saturated)</param>
|
||||
/// <param name="b">Pixel Blue value in range [0, 1] (saturated)</param>
|
||||
protected abstract 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);
|
||||
|
||||
// Buffer to store generator result in
|
||||
private static byte[][] _animationBuffer = null!;
|
||||
|
||||
// Main application reference
|
||||
private static MatrixDesignerMain _form = null!;
|
||||
private static Matrix _preview = null!;
|
||||
private static Matrix _preview = null!; // preview matrix
|
||||
|
||||
public static void GenerateBaseUi(FlowLayoutPanel anchor, Matrix matrix, MatrixDesignerMain form1)
|
||||
{
|
||||
|
@ -79,10 +104,11 @@ namespace Matrix_App
|
|||
// generate access buttons for available generators
|
||||
foreach (var generator in Generators)
|
||||
{
|
||||
// generate button
|
||||
var button = new Button
|
||||
{
|
||||
Width = 215,
|
||||
Text = GetBetterFieldName(generator.GetType().Name)
|
||||
Text = FieldWidgets.GetBetterFieldName(generator.GetType().Name)
|
||||
};
|
||||
button.Click += (sender, e) => OpenGeneratorUi(generator, matrix);
|
||||
button.Image = CreateSnapshot(generator);
|
||||
|
@ -124,16 +150,34 @@ namespace Matrix_App
|
|||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void OpenGeneratorUi(MatrixGifGenerator matrixGifGenerator, Matrix matrix)
|
||||
{
|
||||
_generator = matrixGifGenerator;
|
||||
|
||||
if (!ShowEditDialog(matrix))
|
||||
return;
|
||||
|
||||
FlipColorStoreRG_GR(_animationBuffer, _form.gifBuffer);
|
||||
_form.ResetTimeline();
|
||||
|
||||
if (Renderer.HasWork())
|
||||
{
|
||||
if (DialogResult.Yes ==
|
||||
MessageBox.Show($@"The filter {_generator.GetType().Name} hasn't finished yet, wait for completion?",
|
||||
@"Filter incomplete", MessageBoxButtons.YesNo, MessageBoxIcon.Warning))
|
||||
{
|
||||
BlockBuffer();
|
||||
FlipColorStoreRG_GR(_animationBuffer, MatrixDesignerMain.gifBuffer);
|
||||
_form.ResetTimeline();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show($@"The filter {_generator.GetType().Name} has timedout", @"Failed applying filter", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FlipColorStoreRG_GR(_animationBuffer, MatrixDesignerMain.gifBuffer);
|
||||
_form.ResetTimeline();
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetGlobalArgs(int w, int h, int f, in byte[][]? previous, in byte[][] preview)
|
||||
|
@ -149,6 +193,11 @@ namespace Matrix_App
|
|||
|
||||
private static bool ShowEditDialog(Matrix matrix)
|
||||
{
|
||||
if (_generator == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var success = false;
|
||||
|
||||
Initialize(matrix);
|
||||
|
@ -160,7 +209,7 @@ namespace Matrix_App
|
|||
Text = @"Vorgenerierter Modus: " + _generator.GetType().Name
|
||||
};
|
||||
|
||||
var confirmation = new Button {Text = "Apply", Anchor = AnchorStyles.Top | AnchorStyles.Left};
|
||||
var confirmation = new Button {Text = @"Apply", Anchor = AnchorStyles.Top | AnchorStyles.Left};
|
||||
confirmation.Click += (sender, e) => {
|
||||
success = true;
|
||||
prompt.Close();
|
||||
|
@ -175,20 +224,21 @@ namespace Matrix_App
|
|||
AutoSize = true
|
||||
};
|
||||
|
||||
var fields = _generator.GetType().GetFields();
|
||||
|
||||
PlaybackTimer.Interval = _form.GetDelayTime();
|
||||
PlaybackTimer.Enabled = true;
|
||||
|
||||
var type = _generator.GetType();
|
||||
var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
CreateDivider(controlPanel, 2);
|
||||
foreach (var field in fields)
|
||||
{
|
||||
if (field.IsStatic || !field.IsPublic)
|
||||
var widget = FieldWidgets.GetFieldWidget(field, _generator, InvokeGenerator);
|
||||
|
||||
if (widget == null)
|
||||
continue;
|
||||
|
||||
var fieldValue = field.GetValue(_generator);
|
||||
|
||||
controlPanel.Controls.AddRange(GetFieldUi(field, _generator.GetType(), fieldValue, _generator));
|
||||
controlPanel.Controls.AddRange(widget);
|
||||
CreateDivider(controlPanel, 1);
|
||||
}
|
||||
|
||||
|
@ -218,130 +268,17 @@ namespace Matrix_App
|
|||
return success;
|
||||
}
|
||||
|
||||
private static Control[] GetFieldUi(FieldInfo field, Type clazz, object? fieldValue, MatrixGifGenerator generator)
|
||||
{
|
||||
var panel = new FlowLayoutPanel
|
||||
{
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
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 = ContentAlignment.MiddleLeft,
|
||||
Text = title,
|
||||
Dock = DockStyle.Left,
|
||||
Anchor = AnchorStyles.Top | AnchorStyles.Left,
|
||||
Width = 100
|
||||
});
|
||||
|
||||
switch (fieldValue)
|
||||
{
|
||||
case int value:
|
||||
{
|
||||
var upDown = new NumericUpDown
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Anchor = AnchorStyles.Top | AnchorStyles.Right,
|
||||
Width = 360,
|
||||
Value = value
|
||||
};
|
||||
upDown.ValueChanged += (a, b) =>
|
||||
{
|
||||
field.SetValue(generator, (int) upDown.Value);
|
||||
InvokeGenerator();
|
||||
};
|
||||
|
||||
panel.Controls.Add(upDown);
|
||||
break;
|
||||
}
|
||||
case bool value1:
|
||||
{
|
||||
var upDown = new CheckBox
|
||||
{
|
||||
Dock = DockStyle.Fill, Anchor = AnchorStyles.Top | AnchorStyles.Right, Checked = value1
|
||||
};
|
||||
upDown.CheckedChanged += (a, b) =>
|
||||
{
|
||||
field.SetValue(generator, (bool) upDown.Checked);
|
||||
InvokeGenerator();
|
||||
};
|
||||
|
||||
panel.Controls.Add(upDown);
|
||||
break;
|
||||
}
|
||||
case float floatValue:
|
||||
{
|
||||
var upDown = new TrackBar
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Anchor = AnchorStyles.Top | AnchorStyles.Right,
|
||||
Maximum = 100,
|
||||
Minimum = 0,
|
||||
Value = (int) (floatValue * 100.0f),
|
||||
TickFrequency = 10,
|
||||
Width = 360
|
||||
};
|
||||
upDown.ValueChanged += (a, b) =>
|
||||
{
|
||||
field.SetValue(generator, upDown.Value / 1e2f);
|
||||
InvokeGenerator();
|
||||
};
|
||||
|
||||
panel.Controls.Add(upDown);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new Control[] {description, panel};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a new name from standard class names
|
||||
/// Example: SomeClassA --> some class a
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetBetterFieldName(string name)
|
||||
{
|
||||
var groups = Regex.Match(name, @"([A-Z]*[a-z]+)([A-Z]+[a-z]*)|(.*)").Groups;
|
||||
|
||||
var newName = "";
|
||||
|
||||
for (var c = 1; c < groups.Count; c++)
|
||||
{
|
||||
newName += groups[c].Value.ToLower() + " ";
|
||||
}
|
||||
|
||||
return newName;
|
||||
}
|
||||
|
||||
private static void Initialize(in Matrix matrix)
|
||||
{
|
||||
// Create new initial buffer and copy what ever was in the Gif buffer to it
|
||||
_initialBuffer = CreateImageRGB_NT(matrix.matrixWidth(), matrix.matrixHeight(), _form.gifBuffer.Length);
|
||||
FlipColorStoreRG_GR(_form.gifBuffer, _initialBuffer);
|
||||
|
||||
_initialBuffer = CreateImageRGB_NT(matrix.matrixWidth(), matrix.matrixHeight(), MatrixDesignerMain.gifBuffer.Length);
|
||||
FlipColorStoreRG_GR(MatrixDesignerMain.gifBuffer, _initialBuffer);
|
||||
// Set Generator args
|
||||
SetGlobalArgs(matrix.matrixWidth(),
|
||||
matrix.matrixHeight(),
|
||||
_form.gifBuffer.Length - 1,
|
||||
MatrixDesignerMain.gifBuffer.Length - 1,
|
||||
_initialBuffer,
|
||||
CreateImageRGB_NT(matrix.matrixWidth(), matrix.matrixHeight(), _form.gifBuffer.Length)
|
||||
CreateImageRGB_NT(matrix.matrixWidth(), matrix.matrixHeight(), MatrixDesignerMain.gifBuffer.Length)
|
||||
);
|
||||
|
||||
// Create preview matrix
|
||||
|
@ -356,13 +293,14 @@ namespace Matrix_App
|
|||
/// Adds a separating line to the controls
|
||||
/// </summary>
|
||||
/// <param name="controlPanel"></param>
|
||||
private static void CreateDivider(Control controlPanel, int height)
|
||||
/// <param name="lineHeight"></param>
|
||||
private static void CreateDivider(Control controlPanel, int lineHeight)
|
||||
{
|
||||
var divider = new Label
|
||||
{
|
||||
BorderStyle = BorderStyle.Fixed3D,
|
||||
AutoSize = false,
|
||||
Height = height,
|
||||
Height = lineHeight,
|
||||
Width = 500
|
||||
};
|
||||
|
||||
|
@ -383,7 +321,7 @@ namespace Matrix_App
|
|||
{
|
||||
var v = y / (float)height;
|
||||
|
||||
_generator.ColorFragment(x, y, u, v, frame, out var r, out var g, out var b);
|
||||
_generator!.ColorFragment(x, y, u, v, frame, out var r, out var g, out var b);
|
||||
|
||||
var index = (x + y * width) * 3;
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
using System;
|
||||
using Matrix_App.PregeneratedMods.reflection;
|
||||
using static Matrix_App.GifGeneratorUtils;
|
||||
|
||||
namespace Matrix_App.PregeneratedMods
|
||||
{
|
||||
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;
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Blur size", description: "The side length of the bounding square used to blur in pixels")]
|
||||
private 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)
|
||||
{
|
||||
|
|
|
@ -1,47 +1,58 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Matrix_App.PregeneratedMods.reflection;
|
||||
using static Matrix_App.GifGeneratorUtils;
|
||||
|
||||
namespace Matrix_App.PregeneratedMods
|
||||
{
|
||||
public sealed class ColorAdjust : MatrixGifGenerator
|
||||
public 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;
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Tone offset", description: "Sets an additional offset to the pixels hue")]
|
||||
private float hueOffset = 0.0f;
|
||||
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Saturation boost", description: "Decreases or increases saturation")]
|
||||
private float saturationBoost = 0.5f;
|
||||
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Brightness boost", description: "Decreases or increases brightness")]
|
||||
private 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;
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Red boost", description: "Decreases or increases Red")]
|
||||
private float redBoost = 0.5f;
|
||||
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Green boost", description: "Decreases or increases Green")]
|
||||
private float greenBoost = 0.5f;
|
||||
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Blue boost", description: "Decreases or increases Blue")]
|
||||
private float blueBoost = 0.5f;
|
||||
|
||||
private float boost(float x, float y)
|
||||
private static float Boost(float x, float y)
|
||||
{
|
||||
return Math.Clamp(x + (y - 0.5f) * 2.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
SampleFrame(actualStore, frame, x, y, width, out float tr, out float tg, out float tb);
|
||||
SampleFrame(actualStore!, frame, x, y, width, out float tr, out float tg, out float tb);
|
||||
|
||||
// Adjust HSV
|
||||
HsvFromRgb(tr, tg, tb, out float h, out float s, out float value);
|
||||
|
||||
h = h / 360.0f + hueOffset;
|
||||
h = (h - MathF.Floor(h)) * 360.0f;
|
||||
s = boost(s, saturationBoost);
|
||||
value = boost(value, valueBoost);
|
||||
s = Boost(s, saturationBoost);
|
||||
value = Boost(value, valueBoost);
|
||||
|
||||
// Adjust RGB
|
||||
RgbFromHsv(h, s, value, out tr, out tg, out tb);
|
||||
|
||||
r = boost(tr, redBoost);
|
||||
g = boost(tg, greenBoost);
|
||||
b = boost(tb, blueBoost);
|
||||
r = Boost(tr, redBoost);
|
||||
g = Boost(tg, greenBoost);
|
||||
b = Boost(tb, blueBoost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Matrix_App.PregeneratedMods.reflection;
|
||||
using static Matrix_App.GifGeneratorUtils;
|
||||
|
||||
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;
|
||||
[UiWidget]
|
||||
[UiDescription(title: "use Luminance", description: "Use luminance as defined by ITU-R BT.709 as grayscale output")]
|
||||
private 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)
|
||||
{
|
||||
SampleFrame(actualStore, frame, x, y, width, out float lr, out float lg, out float lb);
|
||||
SampleFrame(actualStore!, frame, x, y, width, out float lr, out float lg, out float lb);
|
||||
|
||||
if (byLuminance)
|
||||
{
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using static Matrix_App.GifGeneratorUtils;
|
||||
using static Matrix_App.GifGeneratorUtils;
|
||||
|
||||
namespace Matrix_App.PregeneratedMods
|
||||
{
|
||||
class Invert : MatrixGifGenerator
|
||||
public sealed class Invert : MatrixGifGenerator
|
||||
{
|
||||
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)
|
||||
{
|
||||
SampleFrame(actualStore, frame, x, y, width, out float lr, out float lg, out float lb);
|
||||
SampleFrame(actualStore!, frame, x, y, width, out float lr, out float lg, out float lb);
|
||||
|
||||
r = 1- lr;
|
||||
g = 1 -lg;
|
||||
b = 1 -lb;
|
||||
r = 1 - lr;
|
||||
g = 1 - lg;
|
||||
b = 1 - lb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,38 +6,38 @@ namespace Matrix_App.PregeneratedMods
|
|||
{
|
||||
public sealed class Rain : MatrixGifGenerator
|
||||
{
|
||||
private float Fract(float x)
|
||||
private static float Fract(float x)
|
||||
{
|
||||
return x - MathF.Floor(x);
|
||||
}
|
||||
|
||||
private float Step(float x, float y)
|
||||
private static float Step(float x, float y)
|
||||
{
|
||||
return y > x ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
private float Shower(float u, float v, float x, float y, float t, float frame)
|
||||
private static float Shower(float u, float v, float x, float y, float t, float frame)
|
||||
{
|
||||
float movY = Fract(v - frame * t + y + MathF.Sin(u * 5.0f) * 0.3f);
|
||||
var movY = Fract(v - frame * t + y + MathF.Sin(u * 5.0f) * 0.3f);
|
||||
|
||||
float opacityX = Step(0.7f, Fract((u + x) * 93.0f));
|
||||
float opacityY = Step(0.6f, movY);
|
||||
var opacityX = Step(0.7f, Fract((u + x) * 93.0f));
|
||||
var opacityY = Step(0.6f, movY);
|
||||
|
||||
float drop = MathF.Pow(movY, 6.0f);
|
||||
var drop = MathF.Pow(movY, 6.0f);
|
||||
|
||||
return opacityX * opacityY * drop;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
float time = frame / (totalFrames * 0.5f);
|
||||
var time = frame / (totalFrames * 0.5f);
|
||||
|
||||
float s1 = Shower(u, v, 0.00f, 0.0f, 1.0f, time);
|
||||
float s2 = Shower(u, v, 3.11f, 0.5f, 1.0f, time);
|
||||
float s3 = Shower(u, v, 3.40f, 0.2f, 0.6f, time);
|
||||
float s4 = Shower(u, v, 3.20f, 0.7f, 0.6f, time);
|
||||
var s1 = Shower(u, v, 0.00f, 0.0f, 1.0f, time);
|
||||
var s2 = Shower(u, v, 3.11f, 0.5f, 1.0f, time);
|
||||
var s3 = Shower(u, v, 3.40f, 0.2f, 0.6f, time);
|
||||
var s4 = Shower(u, v, 3.20f, 0.7f, 0.6f, time);
|
||||
|
||||
float skyLight = (Fract(MathF.Sin(u * v + v) * 67128.0f + time) * 0.3f + 0.7f) * (1.3f - v);
|
||||
var skyLight = (Fract(MathF.Sin(u * v + v) * 67128.0f + time) * 0.3f + 0.7f) * (1.3f - v);
|
||||
|
||||
r = skyLight * 0.1f;
|
||||
g = skyLight * 0.2f;
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
using System;
|
||||
using Matrix_App.PregeneratedMods.reflection;
|
||||
|
||||
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;
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Seed", description: "Just a seed for a bad deterministic random function")]
|
||||
private 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)
|
||||
{
|
||||
r = next(frame, x, y);
|
||||
g = next(frame, x, y + 67);
|
||||
b = next(frame, x, y + 34968);
|
||||
r = Next(frame, x, y);
|
||||
g = Next(frame, x, y + 67);
|
||||
b = Next(frame, x, y + 34968);
|
||||
}
|
||||
|
||||
private float next(int frame, int x, int y)
|
||||
private float Next(int frame, int x, int y)
|
||||
{
|
||||
float k = MathF.Sin(frame * 2356f + (x + y) * 5334f + (y * x) * 534f + 78.0f + seed * 435f) * 567f;
|
||||
var k = MathF.Sin(frame * 2356f + (x + y) * 5334f + (y * x) * 534f + 78.0f + seed * 435f) * 567f;
|
||||
return k - MathF.Floor(k);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,28 @@
|
|||
using System;
|
||||
using Matrix_App.PregeneratedMods.reflection;
|
||||
using static Matrix_App.GifGeneratorUtils;
|
||||
|
||||
namespace Matrix_App.PregeneratedMods
|
||||
{
|
||||
public class SimpleRainbow : MatrixGifGenerator
|
||||
public sealed class SimpleRainbow : MatrixGifGenerator
|
||||
{
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Radial", description: "Uses the angle to alter hues")]
|
||||
public bool radial = false;
|
||||
private bool radial = false;
|
||||
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Saturation", description: "Overall saturation")]
|
||||
public float saturation = 1.0f;
|
||||
private float saturation = 1.0f;
|
||||
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Brightness", description: "Overall brightness")]
|
||||
public float value = 1.0f;
|
||||
private float value = 1.0f;
|
||||
|
||||
[UiWidget]
|
||||
[UiDescription(title: "Hue rotation", description: "Offset for hue calculation")]
|
||||
public float rotation = 0.0f;
|
||||
private float rotation = 0.0f;
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
if (radial)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Matrix_App.PregeneratedMods
|
||||
{
|
||||
|
@ -14,18 +12,18 @@ namespace Matrix_App.PregeneratedMods
|
|||
return clamp(v,0.,1.);
|
||||
}
|
||||
*/
|
||||
private float SpiralCurve(float s, float t, float time)
|
||||
private static float SpiralCurve(float s, float t, float time)
|
||||
{
|
||||
float r = MathF.Sqrt(s * s + t * t);
|
||||
float a = MathF.Atan2(t, s);
|
||||
float v = MathF.Sin(50 * (MathF.Sqrt(r) - 0.02f * a - time));
|
||||
var r = MathF.Sqrt(s * s + t * t);
|
||||
var a = MathF.Atan2(t, s);
|
||||
var v = MathF.Sin(50 * (MathF.Sqrt(r) - 0.02f * a - time));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
float sp = SpiralCurve((u - 0.5f) * 0.1f, (v - 0.5f) * 0.1f, frame / (float) totalFrames);
|
||||
var sp = SpiralCurve((u - 0.5f) * 0.1f, (v - 0.5f) * 0.1f, frame / (float) totalFrames);
|
||||
|
||||
r = sp;
|
||||
g = sp;
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using System;
|
||||
|
||||
namespace Matrix_App.PregeneratedMods
|
||||
{
|
||||
class UvGrid : MatrixGifGenerator
|
||||
public sealed class UvGrid : MatrixGifGenerator
|
||||
{
|
||||
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)
|
||||
{
|
||||
r = u;
|
||||
g = v;
|
||||
b = 0.5f;
|
||||
b = MathF.Sin(frame / (float) totalFrames * MathF.PI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Matrix_App.PregeneratedMods.reflection
|
||||
{
|
||||
public static class FieldWidgets
|
||||
{
|
||||
public delegate void UiEvent();
|
||||
|
||||
public static Control[]? GetFieldWidget(FieldInfo field, object instance, UiEvent eventTask)
|
||||
{
|
||||
if (field.IsStatic || !field.IsDefined(typeof(UiWidget)))
|
||||
return null;
|
||||
|
||||
// fallback
|
||||
return GetDefaultFieldUi(field, field.GetValue(instance), (instance as MatrixGifGenerator)!, eventTask);
|
||||
}
|
||||
|
||||
private static Control[] GetDefaultFieldUi(FieldInfo field, object? fieldValue, MatrixGifGenerator generator, UiEvent eventTask)
|
||||
{
|
||||
var panel = new FlowLayoutPanel
|
||||
{
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
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 = ContentAlignment.MiddleLeft,
|
||||
Text = title,
|
||||
Dock = DockStyle.Left,
|
||||
Anchor = AnchorStyles.Top | AnchorStyles.Left,
|
||||
Width = 100
|
||||
});
|
||||
|
||||
switch (fieldValue)
|
||||
{
|
||||
case int value:
|
||||
{
|
||||
var upDown = new NumericUpDown
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Anchor = AnchorStyles.Top | AnchorStyles.Right,
|
||||
Width = 360,
|
||||
Value = value
|
||||
};
|
||||
upDown.ValueChanged += (a, b) =>
|
||||
{
|
||||
field.SetValue(generator, (int) upDown.Value);
|
||||
eventTask();
|
||||
};
|
||||
|
||||
panel.Controls.Add(upDown);
|
||||
break;
|
||||
}
|
||||
case bool value1:
|
||||
{
|
||||
var upDown = new CheckBox
|
||||
{
|
||||
Dock = DockStyle.Fill, Anchor = AnchorStyles.Top | AnchorStyles.Right, Checked = value1
|
||||
};
|
||||
upDown.CheckedChanged += (a, b) =>
|
||||
{
|
||||
field.SetValue(generator, upDown.Checked);
|
||||
eventTask();
|
||||
};
|
||||
|
||||
panel.Controls.Add(upDown);
|
||||
break;
|
||||
}
|
||||
case float floatValue:
|
||||
{
|
||||
var upDown = new TrackBar
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Anchor = AnchorStyles.Top | AnchorStyles.Right,
|
||||
Maximum = 100,
|
||||
Minimum = 0,
|
||||
Value = (int) (floatValue * 100.0f),
|
||||
TickFrequency = 10,
|
||||
Width = 360
|
||||
};
|
||||
upDown.ValueChanged += (a, b) =>
|
||||
{
|
||||
field.SetValue(generator, upDown.Value / 1e2f);
|
||||
eventTask();
|
||||
};
|
||||
|
||||
panel.Controls.Add(upDown);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new Control[] {description, panel};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a new name from standard class names
|
||||
/// Example: SomeClassA --> some class a
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetBetterFieldName(string name)
|
||||
{
|
||||
var groups = Regex.Match(name, @"([A-Z]*[a-z]+)([A-Z]+[a-z]*)|(.*)").Groups;
|
||||
|
||||
var newName = "";
|
||||
|
||||
for (var c = 1; c < groups.Count; c++)
|
||||
{
|
||||
newName += groups[c].Value.ToLower() + " ";
|
||||
}
|
||||
|
||||
return newName;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace Matrix_App.PregeneratedMods
|
||||
namespace Matrix_App.PregeneratedMods.reflection
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class UiDescriptionAttribute : Attribute
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace Matrix_App.PregeneratedMods.reflection
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class UiWidget : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -143,6 +143,6 @@
|
|||
<value>..\resources\frosch.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Pfüsikuh" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\pfüsikuh.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
<value>..\Resources\Splashcreen.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
Binary file not shown.
After Width: | Height: | Size: 241 KiB |
Binary file not shown.
Before Width: | Height: | Size: 88 KiB |
|
@ -25,7 +25,7 @@ namespace Matrix_App
|
|||
{
|
||||
Name = name,
|
||||
IsBackground = true,
|
||||
Priority = ThreadPriority.BelowNormal
|
||||
Priority = ThreadPriority.Normal
|
||||
};
|
||||
thread.Start();
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ namespace Matrix_App
|
|||
{
|
||||
try
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
Thread.Sleep(10);
|
||||
} catch(ThreadInterruptedException)
|
||||
{
|
||||
thread.Interrupt();
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Text;
|
||||
using static Matrix_App.Defaults;
|
||||
|
||||
namespace Matrix_App
|
||||
|
@ -81,9 +77,9 @@ namespace Matrix_App
|
|||
int index = (x + y * width) * Bpp;
|
||||
|
||||
image.SetPixel(x, y, Color.FromArgb(
|
||||
(byte) buffer[index + 0],
|
||||
(byte) buffer[index + 1],
|
||||
(byte) buffer[index + 2]
|
||||
buffer[index + 0],
|
||||
buffer[index + 1],
|
||||
buffer[index + 2]
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
|||
0e5f843b45897d8b4a3e6250399d748fbf87d606
|
||||
8b5c196e3fff81055e69fb849ea66d181b78d0ae
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,8 @@
|
|||
is_global = true
|
||||
build_property.TargetFramework = netcoreapp3.1
|
||||
build_property.TargetPlatformMinVersion = 7.0
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.PublishSingleFile =
|
||||
build_property.IncludeAllContentForSelfExtract =
|
||||
build_property._SupportedPlatformList = Android,iOS,Linux,macOS,Windows
|
Binary file not shown.
|
@ -1 +1 @@
|
|||
d3ff948d4c991bd397c33d4f33adca3dc910573c
|
||||
d74f4da8e70ffef608fcbd55775b064d0e57aa85
|
||||
|
|
|
@ -59,3 +59,35 @@ F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matri
|
|||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5_RC3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5_RC3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.pdb
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5_RC3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.genruntimeconfig.cache
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\Matrix App.exe
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\Matrix App.deps.json
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\Matrix App.runtimeconfig.json
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\Matrix App.runtimeconfig.dev.json
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\Matrix App.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\Matrix App.pdb
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\Microsoft.Win32.Registry.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\System.CodeDom.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\System.IO.Ports.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\System.Management.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\System.Security.AccessControl.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\System.Security.Principal.Windows.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\runtimes\win\lib\netstandard2.0\Microsoft.Win32.Registry.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\runtimes\win\lib\netstandard2.0\System.IO.Ports.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\runtimes\win\lib\netcoreapp2.0\System.Management.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\runtimes\win\lib\netcoreapp2.0\System.Security.AccessControl.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\runtimes\unix\lib\netcoreapp2.1\System.Security.Principal.Windows.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\bin\Release\netcoreapp3.1\runtimes\win\lib\netcoreapp2.1\System.Security.Principal.Windows.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.csprojAssemblyReference.cache
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix_App.ColorWheel.resources
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix_App.Matrix.resources
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix_App.MatrixDesignerMain.resources
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix_App.Properties.Resources.resources
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.csproj.GenerateResource.cache
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.GeneratedMSBuildEditorConfig.editorconfig
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.AssemblyInfoInputs.cache
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.AssemblyInfo.cs
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.csproj.CoreCompileInputs.cache
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.csproj.CopyComplete
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.dll
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.pdb
|
||||
F:\Content\Schule\BBS-T1-Ludwigshafen\Klasse 12\Info Lk\bulli\Neopixel\App\Matrix_App_V3.5.3\Matrix App\obj\Release\netcoreapp3.1\Matrix App.genruntimeconfig.cache
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
|||
4853592640e68725119800981d81bdaa9a74ded2
|
||||
515eead76ebf0b414116e9f97a694849e0a06bf3
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue