├── .gitignore ├── .nuget ├── NuGet.Config ├── NuGet.exe └── NuGet.targets ├── FerretLib.SFML ├── Chrono.cs ├── ChronoEventArgs.cs ├── Extensions.cs ├── FerretLib.SFML.csproj ├── FerretLib.SFML.csproj.DotSettings ├── FpsCounter.cs ├── FpsLimiter.cs ├── GetRandom.cs ├── IEntity.cs ├── IWorldEngine.cs ├── Properties │ └── AssemblyInfo.cs ├── ScreenSaverEngine.cs ├── ScreenSaverSettings.cs ├── ViewPort.cs ├── ViewportCollection.cs ├── packages.config └── ~Refactor │ └── SystemClock.cs ├── Lib └── SFMLNet 2.1 │ └── x86 │ ├── csfml-audio-2.dll │ ├── csfml-graphics-2.dll │ ├── csfml-window-2.dll │ ├── libsndfile-1.dll │ ├── openal32.dll │ ├── sfmlnet-audio-2.dll │ ├── sfmlnet-graphics-2.dll │ └── sfmlnet-window-2.dll ├── MatrixScreen.ConfigUI ├── MatrixScreen.ConfigUI.csproj ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── frmMain.Designer.cs ├── frmMain.cs └── frmMain.resx ├── MatrixScreen.Core ├── ConfigProvider.cs ├── GlyphConfig.cs ├── GlyphStreamConfig.cs ├── GlyphStreamManagerConfig.cs ├── MatrixConfig.cs ├── MatrixScreen.Core.csproj └── Properties │ └── AssemblyInfo.cs ├── MatrixScreen.sln ├── MatrixScreen ├── ChronoDisplay.cs ├── Debug.cs ├── DebugEngine.cs ├── MatrixEngine.cs ├── MatrixEngine │ ├── Glyph.cs │ ├── GlyphStream.Debug.cs │ ├── GlyphStream.Noise.cs │ ├── GlyphStream.cs │ ├── GlyphStreamManager.cs │ ├── ShaderWrapper.cs │ └── TwitchCalculator.cs ├── MatrixScreen.csproj ├── MatrixScreen.csproj.DotSettings ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── app.config ├── data │ ├── frag.c │ └── vert.c └── packages.config ├── Resources ├── glyphs.png ├── glyphsOutline.png └── lekton.ttf ├── license ├── packages └── repositories.config └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Build and binary folders 2 | [Bb]in/ 3 | [Oo]bj/ 4 | [Dd]ebug/ 5 | [Rr]elease/ 6 | 7 | # Visual Studio cruft 8 | *.[Cc]ache 9 | *.sln.cache 10 | *.sln.docstates 11 | *.suo 12 | *.csproj.user 13 | *.user 14 | *.psess 15 | *.vsp 16 | *.vspx 17 | _UpgradeReport_Files/ 18 | Backup*/ 19 | UpgradeLog*.XML 20 | *.vspscc 21 | *.vssscc 22 | 23 | # Package management cruft 24 | packages/*/* 25 | 26 | # OS-specific cruft 27 | thumbs.db 28 | *.DS_Store 29 | 30 | # Windows Azure cruft 31 | csx 32 | *.build.csdef 33 | 34 | # Third-party add-in cruft 35 | [Tt]est[Rr]esult*/ 36 | _[Rr]e[Ss]harper*/ 37 | *.[Rr]e[Ss]harper.user 38 | *.ncrunch* 39 | .*crunch*.local.xml 40 | *.[Dd]ot[Ss]ettings 41 | 42 | # Misc cruft 43 | ~$* 44 | *.stresult 45 | *.userprefs 46 | *.pidb 47 | *.Publish.xml 48 | *.orig 49 | *.[Tt][Mm][Pp] 50 | *.temp 51 | *.jmconfig 52 | 53 | .vs/ -------------------------------------------------------------------------------- /.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/.nuget/NuGet.exe -------------------------------------------------------------------------------- /.nuget/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\..\ 5 | 6 | 7 | false 8 | 9 | 10 | false 11 | 12 | 13 | true 14 | 15 | 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) 31 | 32 | 33 | 34 | 35 | $(SolutionDir).nuget 36 | 37 | 38 | 39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config 40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config 41 | 42 | 43 | 44 | $(MSBuildProjectDirectory)\packages.config 45 | $(PackagesProjectConfig) 46 | 47 | 48 | 49 | 50 | $(NuGetToolsPath)\NuGet.exe 51 | @(PackageSource) 52 | 53 | "$(NuGetExePath)" 54 | mono --runtime=v4.0.30319 $(NuGetExePath) 55 | 56 | $(TargetDir.Trim('\\')) 57 | 58 | -RequireConsent 59 | -NonInteractive 60 | 61 | "$(SolutionDir) " 62 | "$(SolutionDir)" 63 | 64 | 65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) 66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols 67 | 68 | 69 | 70 | RestorePackages; 71 | $(BuildDependsOn); 72 | 73 | 74 | 75 | 76 | $(BuildDependsOn); 77 | BuildPackage; 78 | 79 | 80 | 81 | 82 | 83 | 84 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 99 | 100 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /FerretLib.SFML/Chrono.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System.Threading; 3 | 4 | namespace FerretLib.SFML 5 | { 6 | internal class Chrono : HighPerformanceTimer 7 | { 8 | private FpsCounter _fps; 9 | protected double _monotonic; 10 | 11 | internal Chrono() : base() 12 | { 13 | long ticks; 14 | QueryPerformanceCounter(out ticks); 15 | _monotonic = ticks * POLL_MULTIPLIER; 16 | 17 | _fps = new FpsCounter(); 18 | } 19 | 20 | internal ChronoEventArgs Update() 21 | { 22 | var ticks = GetTicks(); 23 | 24 | var delta = ticks - _monotonic; 25 | var fps = _fps.Update(ticks); 26 | 27 | _monotonic = ticks; 28 | return new ChronoEventArgs(_monotonic, delta, fps); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /FerretLib.SFML/ChronoEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FerretLib.SFML 4 | { 5 | public class ChronoEventArgs : EventArgs 6 | { 7 | public ChronoEventArgs(double monotonic, double delta, double fps) 8 | { 9 | Monotonic = monotonic; 10 | Delta = delta; 11 | DateTime = DateTime.Now; 12 | Fps = fps; 13 | } 14 | 15 | public double Monotonic { get; private set; } 16 | public double Delta { get; private set; } 17 | public double Fps { get; private set; } 18 | public DateTime DateTime { get; private set; } 19 | } 20 | } -------------------------------------------------------------------------------- /FerretLib.SFML/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using SFML.Graphics; 3 | using SFML.Window; 4 | 5 | namespace FerretLib.SFML 6 | { 7 | public static class Extensions 8 | { 9 | #region Basic conversion 10 | public static Vector2i ToVector2i(this Vector2f input) 11 | { 12 | return new Vector2i((int)input.X, (int)input.Y); 13 | } 14 | 15 | public static Vector2f ToVector2f(this Vector2i input) 16 | { 17 | return new Vector2f(input.X, input.Y); 18 | } 19 | 20 | public static Point ToPoint(this Vector2i input) 21 | { 22 | return new Point(input.X, input.Y); 23 | } 24 | 25 | public static Point ToPoint(this Vector2f input) 26 | { 27 | return new Point((int)input.X, (int)input.Y); 28 | } 29 | 30 | public static Vector2f ToVector2f(this Size input) 31 | { 32 | return new Vector2f(input.Width, input.Height); 33 | } 34 | 35 | public static Vector2f ToVector2f(this Point input) 36 | { 37 | return new Vector2f(input.X, input.Y); 38 | } 39 | 40 | public static Vector2i ToVector2i(this Size input) 41 | { 42 | return new Vector2i(input.Width, input.Height); 43 | } 44 | 45 | public static Vector2i ToVector2i(this Point input) 46 | { 47 | return new Vector2i(input.X, input.Y); 48 | } 49 | 50 | public static Rectangle ToRectangle(this Vector2u input) 51 | { 52 | return new Rectangle(0, 0, (int)input.X, (int)input.Y); 53 | } 54 | 55 | public static IntRect ToIntRect(this Rectangle input) 56 | { 57 | return new IntRect(input.X,input.Y,input.Width,input.Height); 58 | } 59 | #endregion 60 | 61 | #region Rectangle helpers 62 | public static int Bottom(this IntRect input) 63 | { 64 | return input.Top + input.Height; 65 | } 66 | 67 | public static int Right(this IntRect input) 68 | { 69 | return input.Left + input.Width; 70 | } 71 | #endregion 72 | 73 | public static Rectangle Normalize(this Rectangle rectangle) 74 | { 75 | return new Rectangle(0,0,rectangle.Width,rectangle.Height); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FerretLib.SFML/FerretLib.SFML.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {A8A5B3D5-9042-453C-81C7-C66A66F79855} 9 | Library 10 | Properties 11 | FerretLib.SFML 12 | FerretLib.SFML 13 | v3.5 14 | Client 15 | 512 16 | ..\ 17 | true 18 | 19 | 20 | 21 | 22 | x86 23 | true 24 | full 25 | false 26 | bin\Debug\ 27 | TRACE;DEBUG 28 | prompt 29 | 4 30 | 31 | 32 | x86 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | 40 | 41 | 42 | 43 | 44 | 45 | ..\packages\SFML.Net.2.1.5\lib\sfmlnet-audio-2.dll 46 | 47 | 48 | ..\packages\SFML.Net.2.1.5\lib\sfmlnet-graphics-2.dll 49 | 50 | 51 | ..\packages\SFML.Net.2.1.5\lib\sfmlnet-window-2.dll 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 83 | 84 | 85 | 86 | 93 | -------------------------------------------------------------------------------- /FerretLib.SFML/FerretLib.SFML.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | True -------------------------------------------------------------------------------- /FerretLib.SFML/FpsCounter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FerretLib.SFML 4 | { 5 | internal class FpsCounter 6 | { 7 | private long _frames; // Number of frames elapsed since last FPS calculation 8 | private double _nextTicks; // When to next calculate FPS 9 | private float _fps; // Last calculated FPS 10 | 11 | public float Update(double ticks) 12 | { 13 | _frames++; 14 | 15 | if (_nextTicks <= ticks) 16 | { 17 | _fps = (float)Math.Round(_frames * (ticks - _nextTicks + 1f), 2); 18 | _frames = 0; 19 | _nextTicks = ticks + 1f; 20 | } 21 | 22 | return _fps; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /FerretLib.SFML/FpsLimiter.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System.Threading; 3 | 4 | namespace FerretLib.SFML 5 | { 6 | internal class FpsLimiter : HighPerformanceTimer 7 | { 8 | private double _frequency; 9 | private double _nextTime; 10 | 11 | public void SetTargetFps(int targetFps) 12 | { 13 | _frequency = 1f / targetFps; 14 | } 15 | 16 | public FpsLimiter(int targetFps) 17 | { 18 | SetTargetFps(targetFps); 19 | _nextTime = GetTicks(); 20 | } 21 | 22 | internal void Sleep() 23 | { 24 | while (GetTicks() < _nextTime) Thread.Sleep(1); 25 | _nextTime += _frequency; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /FerretLib.SFML/GetRandom.cs: -------------------------------------------------------------------------------- 1 | using SFML.Window; 2 | 3 | namespace FerretLib.SFML 4 | { 5 | public static class GetRandom 6 | { 7 | private static System.Random _randomNumber; 8 | 9 | private static System.Random RandomNumber 10 | { 11 | get { _randomNumber = _randomNumber ?? new System.Random(); return _randomNumber; } 12 | } 13 | 14 | public static float Float(float max = float.MaxValue) 15 | { 16 | return Float(0, max); 17 | } 18 | 19 | public static float Float(float min, float max) 20 | { 21 | return (float) Double(min, max); 22 | } 23 | 24 | public static double Double(double max = double.MaxValue) 25 | { 26 | return Double(0,max); 27 | } 28 | 29 | public static double Double(double min, double max) 30 | { 31 | return (RandomNumber.NextDouble()*(max - min)) + min; 32 | } 33 | 34 | public static int Int(int max = int.MaxValue) 35 | { 36 | return Int(0, max); 37 | } 38 | 39 | public static int Int(int min, int max) 40 | { 41 | return RandomNumber.Next(min, max); 42 | } 43 | 44 | public static bool Bool(float chanceOfTrue = 0.5f) 45 | { 46 | return Double(0, 1f) <= chanceOfTrue; 47 | } 48 | 49 | public static byte Byte(byte max = byte.MaxValue) 50 | { 51 | return Byte(0, max); 52 | } 53 | 54 | public static byte Byte(byte min, byte max) 55 | { 56 | return (byte)Int(min, max); 57 | } 58 | 59 | public static Vector2f Vector2f(float minX, float maxX, float minY, float maxY) 60 | { 61 | return new Vector2f( 62 | Float(minX, maxX), 63 | Float(minY, maxY) 64 | ); 65 | } 66 | 67 | public static Vector2i Vector2i(int minX, int maxX, int minY, int maxY) 68 | { 69 | return new Vector2i( 70 | Int(minX, maxX), 71 | Int(minY, maxY) 72 | ); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /FerretLib.SFML/IEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SFML.Graphics; 3 | 4 | namespace FerretLib.SFML 5 | { 6 | public interface IEntity 7 | { 8 | void Render(RenderTarget target); 9 | void Update(ChronoEventArgs chronoArgs); 10 | } 11 | } -------------------------------------------------------------------------------- /FerretLib.SFML/IWorldEngine.cs: -------------------------------------------------------------------------------- 1 | namespace FerretLib.SFML 2 | { 3 | public interface IWorldEngine : IEntity 4 | { 5 | void Initialise(ViewPortCollection viewports); 6 | } 7 | } -------------------------------------------------------------------------------- /FerretLib.SFML/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SFML.NET Tutorial 01")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Sai Global")] 12 | [assembly: AssemblyProduct("SFML.NET Tutorial 01")] 13 | [assembly: AssemblyCopyright("Copyright © Sai Global 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("6b0475c9-27c7-49ec-8a8e-16c9d868d9d3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /FerretLib.SFML/ScreenSaverEngine.cs: -------------------------------------------------------------------------------- 1 | using SFML.Graphics; 2 | using Sfml = SFML; 3 | using SFML.Window; 4 | 5 | namespace FerretLib.SFML 6 | { 7 | public class ScreenSaverEngine 8 | { 9 | public IWorldEngine Engine { get; set; } 10 | 11 | private readonly ViewPortCollection _viewPorts; 12 | private RenderTexture _canvas; 13 | 14 | private readonly Chrono _chrono; 15 | private readonly FpsLimiter _fpsLimiter; 16 | private bool _isFinished = false; 17 | 18 | /// 19 | /// .ctor 20 | /// 21 | public ScreenSaverEngine(ScreenSaverSettings settings) 22 | { 23 | _viewPorts = new ViewPortCollection(settings.IsFullscreen, settings.IsMultiMonitorEnabled); 24 | _canvas = new RenderTexture((uint) _viewPorts.WorkingArea.Width, (uint) _viewPorts.WorkingArea.Height, false); 25 | _canvas.Clear(Color.Black); 26 | _canvas.Display(); // Needed due to FBO causing inverted co-ords otherwise 27 | _chrono = new Chrono(); 28 | _fpsLimiter = new FpsLimiter(settings.MaxFps); 29 | } 30 | 31 | /// 32 | /// Tell instance to exit main loop after next iteration 33 | /// 34 | public void EndLoop() 35 | { 36 | _isFinished = true; 37 | } 38 | 39 | #region Common helpers 40 | public void BindEscapeToExit() 41 | { 42 | _viewPorts.KeyPressed += (o, e) => { if (e.Code == Keyboard.Key.Escape) _isFinished = true; }; 43 | } 44 | #endregion 45 | 46 | /// 47 | /// Main loop 48 | /// 49 | public void Run() 50 | { 51 | Engine.Initialise(_viewPorts); 52 | 53 | while (!_isFinished) 54 | { 55 | _fpsLimiter.Sleep(); 56 | 57 | var updateArgs = _chrono.Update(); 58 | 59 | _viewPorts.HandleEvents(); 60 | Engine.Update(updateArgs); 61 | Engine.Render(_canvas); 62 | 63 | _viewPorts.Draw(_canvas); 64 | } 65 | } 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /FerretLib.SFML/ScreenSaverSettings.cs: -------------------------------------------------------------------------------- 1 | namespace FerretLib.SFML 2 | { 3 | public class ScreenSaverSettings 4 | { 5 | public bool IsFullscreen = true; 6 | public bool IsMultiMonitorEnabled = true; 7 | public int MaxFps = 60; 8 | } 9 | } -------------------------------------------------------------------------------- /FerretLib.SFML/ViewPort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | using SFML.Graphics; 5 | using SFML.Window; 6 | 7 | namespace FerretLib.SFML 8 | { 9 | /// 10 | /// * Add a debug text output helper / shortcut 11 | /// 12 | public class ViewPort : IDisposable 13 | { 14 | public ViewPortCollection Parent { get; protected set; } 15 | 16 | public RenderWindow Window { get; protected set; } 17 | 18 | /// 19 | /// Keeps track of the viewport's position relative to the total desktop/display area available 20 | /// 21 | public Rectangle WorkingArea { get; protected set; } 22 | 23 | /// 24 | /// Index; only useful for multiple monitors 25 | /// 26 | public readonly int ID; 27 | 28 | public ViewPort(ViewPortCollection parent, Screen screen, int id, bool isFullScreen) 29 | { 30 | ID = id; 31 | Parent = parent; 32 | 33 | Styles style; 34 | 35 | if (isFullScreen) 36 | { 37 | style = Styles.Fullscreen; 38 | WorkingArea = new Rectangle( 39 | screen.Bounds.X, 40 | screen.Bounds.Y, 41 | screen.Bounds.Width, // - 1 42 | screen.Bounds.Height); // - 1 43 | } else { 44 | style = Styles.Resize; 45 | WorkingArea = new Rectangle( 46 | screen.WorkingArea.Left, 47 | screen.WorkingArea.Top, 48 | (int)(screen.WorkingArea.Width * 0.5), 49 | (int)(screen.WorkingArea.Height * 0.5) 50 | ); 51 | } 52 | 53 | Window = new RenderWindow( 54 | new VideoMode( 55 | (uint)WorkingArea.Width, 56 | (uint)WorkingArea.Height 57 | ), 58 | "Screensaver [debug]", 59 | style, 60 | new ContextSettings(32, 0, 0) 61 | ); 62 | 63 | Window.Position = new Vector2i(WorkingArea.Left, WorkingArea.Top); 64 | Window.SetTitle(Window.Position.X + "," + Window.Position.Y); 65 | } 66 | 67 | public Vector2f GetLocalCoordinates(Vector2i input) 68 | { 69 | return Parent.GetLocalCoordinates(input, this); 70 | } 71 | 72 | #region IDisposable Support 73 | private bool _isDisposed; 74 | 75 | void IDisposable.Dispose() 76 | { 77 | GC.SuppressFinalize(this); 78 | } 79 | 80 | protected virtual void Dispose(bool isDisposing) 81 | { 82 | if(_isDisposed) return; 83 | if(Window != null) Window.Close(); 84 | Window = null; 85 | 86 | // Any other unmanaged graphics stuff - release here 87 | 88 | _isDisposed = true; 89 | } 90 | #endregion 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /FerretLib.SFML/ViewportCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Drawing; 5 | using System.Linq; 6 | using System.Runtime.Remoting.Services; 7 | using System.Windows.Forms; 8 | using SFML.Graphics; 9 | using SFML.Window; 10 | using Color = SFML.Graphics.Color; 11 | using KeyEventArgs = SFML.Window.KeyEventArgs; 12 | 13 | namespace FerretLib.SFML 14 | { 15 | public class ViewPortCollection : IEnumerable 16 | { 17 | public List ViewPorts 18 | { 19 | get; 20 | protected set; 21 | } 22 | public Rectangle WorkingArea 23 | { 24 | get; 25 | protected set; 26 | } 27 | 28 | public ViewPortCollection(bool isFullScreen, bool isMultiMonitor) 29 | { 30 | ViewPorts = new List(); 31 | 32 | if (isMultiMonitor) 33 | { 34 | int index = 0; 35 | foreach (var screen in Screen.AllScreens) 36 | { 37 | ViewPorts.Add(new ViewPort(this, screen, index++, isFullScreen)); 38 | } 39 | } 40 | else 41 | { 42 | ViewPorts.Add(new ViewPort(this, Screen.PrimaryScreen, 0, isFullScreen)); 43 | } 44 | 45 | foreach (var viewPort in ViewPorts) { 46 | viewPort.Window.KeyPressed += (o, e) => { 47 | if (KeyPressed != null) 48 | KeyPressed(viewPort, e); 49 | }; 50 | viewPort.Window.KeyReleased += (o, e) => { 51 | if (KeyReleased != null) 52 | KeyReleased(viewPort, e); 53 | }; 54 | viewPort.Window.MouseMoved += (o, e) => { 55 | if (MouseMoved != null) 56 | MouseMoved(viewPort, e); 57 | }; 58 | viewPort.Window.MouseButtonPressed += (o, e) => { 59 | if (MouseButtonPressed != null) 60 | MouseButtonPressed(viewPort, e); 61 | }; 62 | viewPort.Window.MouseButtonReleased += (o, e) => { 63 | if (MouseButtonReleased != null) 64 | MouseButtonReleased(viewPort, e); 65 | }; 66 | viewPort.Window.MouseWheelMoved += (o, e) => { 67 | if (MouseWheelMoved != null) 68 | MouseWheelMoved(viewPort, e); 69 | }; 70 | } 71 | 72 | WorkingArea = GetWorkingArea(ViewPorts); 73 | } 74 | 75 | public Vector2i CursorPosition() 76 | { 77 | return new Vector2i( 78 | Mouse.GetPosition().X - WorkingArea.Left, 79 | Mouse.GetPosition().Y - WorkingArea.Top 80 | ); 81 | } 82 | 83 | private Rectangle GetWorkingArea(List viewPorts) 84 | { 85 | var result = new Rectangle { 86 | X = viewPorts.Select(x => x.WorkingArea.X).Min(), 87 | Y = viewPorts.Select(x => x.WorkingArea.Y).Min() 88 | }; 89 | result.Height = viewPorts.Select(x => x.WorkingArea.Bottom).Max() - result.Y; 90 | result.Width = viewPorts.Select(x => x.WorkingArea.Right).Max() - result.X; 91 | return result; 92 | } 93 | 94 | public Vector2f GetLocalCoordinates(Vector2i globalCoordinates, ViewPort viewport) 95 | { 96 | if (viewport.ID == 0) 97 | return new Vector2f( 98 | globalCoordinates.X - -(viewport.WorkingArea.Left), 99 | globalCoordinates.Y - -(viewport.WorkingArea.Top) 100 | ); 101 | int x = globalCoordinates.X - viewport.WorkingArea.Left; 102 | int y = globalCoordinates.Y - viewport.WorkingArea.Top; 103 | 104 | return new Vector2f(x, y); 105 | } 106 | 107 | #region IEnumerable support 108 | public IEnumerator GetEnumerator() 109 | { 110 | return ViewPorts.GetEnumerator(); 111 | } 112 | 113 | IEnumerator IEnumerable.GetEnumerator() 114 | { 115 | return GetEnumerator(); 116 | } 117 | #endregion 118 | 119 | public void HandleEvents() 120 | { 121 | ViewPorts.ForEach(x => x.Window.DispatchEvents()); 122 | } 123 | 124 | #region Event goodness 125 | public delegate void KeyPressedHandler(ViewPort source, KeyEventArgs args); 126 | public delegate void KeyReleasedHandler(ViewPort source, KeyEventArgs args); 127 | public delegate void MouseMovedHandler(ViewPort source, MouseMoveEventArgs args); 128 | public delegate void MouseButtonPressedHandler(ViewPort source, MouseButtonEventArgs args); 129 | public delegate void MouseButtonReleasedHandler(ViewPort source, MouseButtonEventArgs args); 130 | public delegate void MouseWheelMovedHandler(ViewPort source, MouseWheelEventArgs args); 131 | 132 | public event KeyPressedHandler KeyPressed; 133 | public event KeyReleasedHandler KeyReleased; 134 | public event MouseMovedHandler MouseMoved; 135 | public event MouseButtonPressedHandler MouseButtonPressed; 136 | public event MouseButtonReleasedHandler MouseButtonReleased; 137 | public event MouseWheelMovedHandler MouseWheelMoved; 138 | #endregion 139 | 140 | // shitty hack 141 | Shape hack = new RectangleShape(new Vector2f(0,0)){FillColor = new Color(0,0,0,0)}; 142 | 143 | public void Draw(RenderTexture canvas) 144 | { 145 | var sprite = new Sprite(canvas.Texture) 146 | { 147 | Position = new Vector2f() 148 | }; 149 | 150 | foreach (var viewport in ViewPorts) 151 | { 152 | viewport.Window.Clear(Color.Black); 153 | var rect = new IntRect( 154 | viewport.Window.Position.X - WorkingArea.Left, 155 | viewport.Window.Position.Y - WorkingArea.Top, 156 | viewport.WorkingArea.Width, 157 | viewport.WorkingArea.Height); 158 | sprite.TextureRect = rect; 159 | viewport.Window.Draw(sprite, RenderStates.Default); 160 | } 161 | 162 | ViewPorts.ForEach(x => x.Window.Draw(hack)); 163 | ViewPorts.ForEach(x => x.Window.Display()); 164 | } 165 | } 166 | } -------------------------------------------------------------------------------- /FerretLib.SFML/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /FerretLib.SFML/~Refactor/SystemClock.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace FerretLib.SFML 4 | { 5 | /// 6 | /// TODO: move to appropriate FerretLib 7 | /// 8 | internal class HighPerformanceTimer 9 | { 10 | [DllImport("Kernel32.dll")] 11 | protected static extern bool QueryPerformanceCounter(out long lpPerformanceCount); 12 | 13 | [DllImport("Kernel32.dll")] 14 | protected static extern bool QueryPerformanceFrequency(out long lpFrequency); 15 | 16 | private readonly long POLL_INTERVAL; // Number of 'ticks' per second 17 | protected readonly double POLL_MULTIPLIER; // Multiply by this to convert ticks to seconds 18 | 19 | public HighPerformanceTimer() 20 | { 21 | QueryPerformanceFrequency(out POLL_INTERVAL); 22 | POLL_MULTIPLIER = 1d / POLL_INTERVAL; 23 | } 24 | 25 | public double GetTicks() 26 | { 27 | long ticks; 28 | QueryPerformanceCounter(out ticks); 29 | return ticks * POLL_MULTIPLIER; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Lib/SFMLNet 2.1/x86/csfml-audio-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Lib/SFMLNet 2.1/x86/csfml-audio-2.dll -------------------------------------------------------------------------------- /Lib/SFMLNet 2.1/x86/csfml-graphics-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Lib/SFMLNet 2.1/x86/csfml-graphics-2.dll -------------------------------------------------------------------------------- /Lib/SFMLNet 2.1/x86/csfml-window-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Lib/SFMLNet 2.1/x86/csfml-window-2.dll -------------------------------------------------------------------------------- /Lib/SFMLNet 2.1/x86/libsndfile-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Lib/SFMLNet 2.1/x86/libsndfile-1.dll -------------------------------------------------------------------------------- /Lib/SFMLNet 2.1/x86/openal32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Lib/SFMLNet 2.1/x86/openal32.dll -------------------------------------------------------------------------------- /Lib/SFMLNet 2.1/x86/sfmlnet-audio-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Lib/SFMLNet 2.1/x86/sfmlnet-audio-2.dll -------------------------------------------------------------------------------- /Lib/SFMLNet 2.1/x86/sfmlnet-graphics-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Lib/SFMLNet 2.1/x86/sfmlnet-graphics-2.dll -------------------------------------------------------------------------------- /Lib/SFMLNet 2.1/x86/sfmlnet-window-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Lib/SFMLNet 2.1/x86/sfmlnet-window-2.dll -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/MatrixScreen.ConfigUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {84000BDE-7578-413D-94E8-9C0732D24EC1} 8 | WinExe 9 | Properties 10 | MatrixScreen.ConfigUI 11 | MatrixScreen.ConfigUI 12 | v4.0 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Form 49 | 50 | 51 | frmMain.cs 52 | 53 | 54 | 55 | 56 | frmMain.cs 57 | 58 | 59 | ResXFileCodeGenerator 60 | Resources.Designer.cs 61 | Designer 62 | 63 | 64 | True 65 | Resources.resx 66 | 67 | 68 | SettingsSingleFileGenerator 69 | Settings.Designer.cs 70 | 71 | 72 | True 73 | Settings.settings 74 | True 75 | 76 | 77 | 78 | 79 | {518695b2-f450-4cc1-9e8f-ddce94c3def9} 80 | MatrixScreen 81 | 82 | 83 | 84 | 91 | -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace MatrixScreen.ConfigUI 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new frmMain()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MatrixScreen.ConfigUI")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MatrixScreen.ConfigUI")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("082eeb02-d875-4ac2-a29b-c85e24aa7fa3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18408 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MatrixScreen.ConfigUI.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MatrixScreen.ConfigUI.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18408 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MatrixScreen.ConfigUI.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/frmMain.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MatrixScreen.ConfigUI 2 | { 3 | partial class frmMain 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.button1 = new System.Windows.Forms.Button(); 32 | this.SuspendLayout(); 33 | // 34 | // button1 35 | // 36 | this.button1.Location = new System.Drawing.Point(12, 12); 37 | this.button1.Name = "button1"; 38 | this.button1.Size = new System.Drawing.Size(128, 47); 39 | this.button1.TabIndex = 0; 40 | this.button1.Text = "Add Scatterglyph Layer"; 41 | this.button1.UseVisualStyleBackColor = true; 42 | // 43 | // frmMain 44 | // 45 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 46 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 47 | this.ClientSize = new System.Drawing.Size(694, 418); 48 | this.Controls.Add(this.button1); 49 | this.Name = "frmMain"; 50 | this.Text = "MatrixScreen Configuration"; 51 | this.ResumeLayout(false); 52 | 53 | } 54 | 55 | #endregion 56 | 57 | private System.Windows.Forms.Button button1; 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/frmMain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | namespace MatrixScreen.ConfigUI 11 | { 12 | public partial class frmMain : Form 13 | { 14 | public frmMain() 15 | { 16 | InitializeComponent(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MatrixScreen.ConfigUI/frmMain.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /MatrixScreen.Core/ConfigProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MatrixScreen 4 | { 5 | 6 | /// 7 | /// TODO: 8 | /// Configure keyboard exit 9 | /// Configure mouse exit threshold 10 | /// 11 | public static class ConfigProvider 12 | { 13 | public static MatrixConfig GetConfig() 14 | { 15 | var result = GetDevConfig(); 16 | result.FpsLimit = 60; 17 | result.IsFullscreen = true; 18 | return result; 19 | } 20 | 21 | public static MatrixConfig GetDevConfig() 22 | { 23 | var smallConfigGlitch = GlyphStreamManagerConfig.Mini(); 24 | smallConfigGlitch.MaximumGlyphStreams = 100; 25 | smallConfigGlitch.ShaderType = GlyphStreamManagerConfig.SHADER_GLITCH; 26 | 27 | var bigConfigNoGlitch = GlyphStreamManagerConfig.BigFew(); 28 | bigConfigNoGlitch.ShaderType = null; 29 | var bigConfigGlitch = GlyphStreamManagerConfig.BigFew(); 30 | bigConfigGlitch.MaximumGlyphStreams = 2; 31 | var bigConfigGhost = GlyphStreamManagerConfig.BigFew(); 32 | bigConfigGhost.MaximumGlyphStreams = 2; 33 | bigConfigGhost.ShaderType = GlyphStreamManagerConfig.SHADER_GHOST; 34 | 35 | return new MatrixConfig 36 | { 37 | FpsLimit = 60, 38 | IsFullscreen = true, 39 | IsMultipleMonitorEnabled = true, 40 | RenderLayers = new List{ 41 | smallConfigGlitch, 42 | smallConfigGlitch, 43 | smallConfigGlitch, 44 | smallConfigGlitch, 45 | smallConfigGlitch, 46 | bigConfigNoGlitch, 47 | bigConfigGlitch, 48 | bigConfigGlitch, 49 | bigConfigGlitch, 50 | bigConfigGhost, 51 | }, 52 | }; 53 | } 54 | 55 | public static MatrixConfig GetNormalConfig() 56 | { 57 | return new MatrixConfig 58 | { 59 | FpsLimit = 60, 60 | IsFullscreen = true, 61 | IsMultipleMonitorEnabled = true, 62 | 63 | RenderLayers = new List{ 64 | GlyphStreamManagerConfig.Big(), 65 | }, 66 | }; 67 | } 68 | 69 | public static MatrixConfig GetDebugConfig() 70 | { 71 | return new MatrixConfig 72 | { 73 | FpsLimit = 60, 74 | IsFullscreen = false, 75 | IsMultipleMonitorEnabled = false, 76 | 77 | RenderLayers = new List{ 78 | GlyphStreamManagerConfig.Debug(), 79 | }, 80 | }; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /MatrixScreen.Core/GlyphConfig.cs: -------------------------------------------------------------------------------- 1 | namespace MatrixScreen 2 | { 3 | public class GlyphConfig 4 | { 5 | public byte MinR { get; set; } 6 | public byte MaxR { get; set; } 7 | public byte MinG { get; set; } 8 | public byte MaxG { get; set; } 9 | public byte MinB { get; set; } 10 | public byte MaxB { get; set; } 11 | public byte MinA { get; set; } 12 | public byte MaxA { get; set; } 13 | 14 | public float BrightnessVariation { get; set; } 15 | 16 | public float LightFlickerAlphaMaxVariation { get; set; } 17 | public byte HeavyFlickerMaxAlpha { get; set; } 18 | public byte HeavyFlickerMinAlpha { get; set; } 19 | public float HeavyFickerAlphaVariation { get; set; } 20 | 21 | public float ChanceOfHeavyFlicker { get; set; } 22 | // TODO: heavyflicker duration? 23 | 24 | public static GlyphConfig Default() 25 | { 26 | return new GlyphConfig 27 | { 28 | MinR = 0, 29 | MaxR = 128, 30 | MinG = 224, 31 | MaxG = 255, 32 | MinB = 0, 33 | MaxB = 64, 34 | MinA = 160, 35 | MaxA = 255, 36 | BrightnessVariation = 0.2f, 37 | LightFlickerAlphaMaxVariation = 0.1f, 38 | HeavyFlickerMinAlpha = 32, 39 | HeavyFlickerMaxAlpha = 128, 40 | HeavyFickerAlphaVariation = 0.1f, 41 | 42 | ChanceOfHeavyFlicker = 0.01f, 43 | }; 44 | } 45 | 46 | public static GlyphConfig Bright() 47 | { 48 | return new GlyphConfig 49 | { 50 | MinR = 0, 51 | MaxR = 128, 52 | MinG = 224, 53 | MaxG = 255, 54 | MinB = 0, 55 | MaxB = 64, 56 | MinA = 239, 57 | MaxA = 255, 58 | BrightnessVariation = 0f, 59 | LightFlickerAlphaMaxVariation = 0.1f, 60 | HeavyFlickerMinAlpha = 0, 61 | HeavyFlickerMaxAlpha = 16, 62 | HeavyFickerAlphaVariation = 0.1f, 63 | 64 | ChanceOfHeavyFlicker = 0.01f, 65 | }; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /MatrixScreen.Core/GlyphStreamConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MatrixScreen 4 | { 5 | public class GlyphStreamConfig 6 | { 7 | public int MaxGlyphs { get; set; } 8 | public int MinGlyphs { get; set; } 9 | public float MaxMovementRate { get; set; } 10 | public float MinMovementRate { get; set; } 11 | public float MaxGlyphScale { get; set; } 12 | public float MinGlyphScale{ get; set; } 13 | 14 | /// 15 | /// 1 for normal; lower for glyphs closer together vertically 16 | /// 17 | public float MarginScale { get; set; } 18 | 19 | public GlyphConfig GlyphConfig { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /MatrixScreen.Core/GlyphStreamManagerConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | 3 | namespace MatrixScreen 4 | { 5 | public class GlyphStreamManagerConfig 6 | { 7 | public const string SHADER_GLITCH = @"GLITCH"; 8 | public const string SHADER_GHOST = @"GHOST"; 9 | 10 | public GlyphStreamConfig GlyphStreamConfig { get; private set; } 11 | 12 | public int MaximumGlyphStreams; 13 | public float ChanceOfNewGlyphStream; 14 | public string ShaderType; 15 | 16 | internal static GlyphStreamManagerConfig Debug() 17 | { 18 | return new GlyphStreamManagerConfig() 19 | { 20 | MaximumGlyphStreams = 1, 21 | ChanceOfNewGlyphStream = 1, 22 | 23 | GlyphStreamConfig = new GlyphStreamConfig() 24 | { 25 | MaxGlyphs = 20, 26 | MinGlyphs = 3, 27 | MaxMovementRate = 300f, 28 | MinMovementRate = 40f, 29 | 30 | MinGlyphScale = 0.05f, 31 | MaxGlyphScale = 0.4f, 32 | 33 | GlyphConfig = GlyphConfig.Default(), 34 | }, 35 | }; 36 | } 37 | 38 | internal static GlyphStreamManagerConfig Mini() 39 | { 40 | return new GlyphStreamManagerConfig() 41 | { 42 | MaximumGlyphStreams = 800, 43 | ChanceOfNewGlyphStream = 0.31f, 44 | ShaderType = SHADER_GHOST, 45 | GlyphStreamConfig = new GlyphStreamConfig(){ 46 | MaxGlyphs = 20, 47 | MinGlyphs = 3, 48 | MaxMovementRate = 300f, 49 | MinMovementRate = 40f, 50 | 51 | MinGlyphScale= 0.02f, 52 | MaxGlyphScale = 0.055f, 53 | MarginScale = 0.8f, 54 | 55 | GlyphConfig = GlyphConfig.Default(), 56 | }, 57 | }; 58 | } 59 | 60 | internal static GlyphStreamManagerConfig Big() 61 | { 62 | return new GlyphStreamManagerConfig() 63 | { 64 | MaximumGlyphStreams = 50, 65 | ChanceOfNewGlyphStream = 0.03f, 66 | GlyphStreamConfig = new GlyphStreamConfig() 67 | { 68 | MaxGlyphs = 20, 69 | MinGlyphs = 3, 70 | MaxMovementRate = 300f, 71 | MinMovementRate = 40f, 72 | 73 | MinGlyphScale = 0.02f, 74 | MaxGlyphScale = 0.36f, 75 | MarginScale = 0.8f, 76 | 77 | GlyphConfig = GlyphConfig.Bright(), 78 | }, 79 | }; 80 | } 81 | 82 | internal static GlyphStreamManagerConfig BigFew() 83 | { 84 | return new GlyphStreamManagerConfig() 85 | { 86 | MaximumGlyphStreams = 6, 87 | ChanceOfNewGlyphStream = 0.09f, 88 | ShaderType = SHADER_GLITCH, 89 | 90 | GlyphStreamConfig = new GlyphStreamConfig() 91 | { 92 | MaxGlyphs = 20, 93 | MinGlyphs = 3, 94 | MaxMovementRate = 300f, 95 | MinMovementRate = 30f, 96 | 97 | MinGlyphScale = 0.08f, 98 | MaxGlyphScale = 0.2f, 99 | MarginScale = 0.8f, 100 | 101 | GlyphConfig = GlyphConfig.Bright(), 102 | }, 103 | }; 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /MatrixScreen.Core/MatrixConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MatrixScreen 4 | { 5 | public class MatrixConfig 6 | { 7 | public bool IsFullscreen; 8 | public bool IsMultipleMonitorEnabled; 9 | 10 | public int FpsLimit; 11 | 12 | public List RenderLayers { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MatrixScreen.Core/MatrixScreen.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EC21F371-D920-4485-9E87-0FFB0A114FED} 8 | Library 9 | Properties 10 | MatrixScreen 11 | MatrixScreen.Core 12 | v3.5 13 | 512 14 | Client 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 57 | -------------------------------------------------------------------------------- /MatrixScreen.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MatrixScreen.Core")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MatrixScreen.Core")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c60cfa00-eb57-44e0-8d0f-cd938b50ed3e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MatrixScreen.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2026 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FerretLib.SFML", "FerretLib.SFML\FerretLib.SFML.csproj", "{A8A5B3D5-9042-453C-81C7-C66A66F79855}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixScreen", "MatrixScreen\MatrixScreen.csproj", "{518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{01A4DEA5-E49B-41F4-BC59-97D8515D3EE5}" 11 | ProjectSection(SolutionItems) = preProject 12 | .nuget\NuGet.Config = .nuget\NuGet.Config 13 | .nuget\NuGet.exe = .nuget\NuGet.exe 14 | .nuget\NuGet.targets = .nuget\NuGet.targets 15 | EndProjectSection 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixScreen.ConfigUI", "MatrixScreen.ConfigUI\MatrixScreen.ConfigUI.csproj", "{84000BDE-7578-413D-94E8-9C0732D24EC1}" 18 | EndProject 19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixScreen.Core", "MatrixScreen.Core\MatrixScreen.Core.csproj", "{EC21F371-D920-4485-9E87-0FFB0A114FED}" 20 | EndProject 21 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution items", "{F1EE6F72-5FBF-410D-AE5A-069F7EDBFBB4}" 22 | ProjectSection(SolutionItems) = preProject 23 | .gitignore = .gitignore 24 | license = license 25 | readme.md = readme.md 26 | EndProjectSection 27 | EndProject 28 | Global 29 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 30 | Debug|Any CPU = Debug|Any CPU 31 | Debug|Mixed Platforms = Debug|Mixed Platforms 32 | Debug|x86 = Debug|x86 33 | Release|Any CPU = Release|Any CPU 34 | Release|Mixed Platforms = Release|Mixed Platforms 35 | Release|x86 = Release|x86 36 | EndGlobalSection 37 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 38 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Debug|Any CPU.ActiveCfg = Debug|x86 39 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 40 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Debug|Mixed Platforms.Build.0 = Debug|x86 41 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Debug|x86.ActiveCfg = Debug|x86 42 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Debug|x86.Build.0 = Debug|x86 43 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Release|Any CPU.ActiveCfg = Release|x86 44 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Release|Mixed Platforms.ActiveCfg = Release|x86 45 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Release|Mixed Platforms.Build.0 = Release|x86 46 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Release|x86.ActiveCfg = Release|x86 47 | {A8A5B3D5-9042-453C-81C7-C66A66F79855}.Release|x86.Build.0 = Release|x86 48 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Debug|Any CPU.ActiveCfg = Debug|x86 49 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 50 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Debug|Mixed Platforms.Build.0 = Debug|x86 51 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Debug|x86.ActiveCfg = Debug|x86 52 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Debug|x86.Build.0 = Debug|x86 53 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Release|Any CPU.ActiveCfg = Release|x86 54 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Release|Mixed Platforms.ActiveCfg = Release|x86 55 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Release|Mixed Platforms.Build.0 = Release|x86 56 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Release|x86.ActiveCfg = Release|x86 57 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9}.Release|x86.Build.0 = Release|x86 58 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 61 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 62 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Debug|x86.ActiveCfg = Debug|Any CPU 63 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Release|Any CPU.ActiveCfg = Release|Any CPU 64 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Release|Any CPU.Build.0 = Release|Any CPU 65 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 66 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Release|Mixed Platforms.Build.0 = Release|Any CPU 67 | {84000BDE-7578-413D-94E8-9C0732D24EC1}.Release|x86.ActiveCfg = Release|Any CPU 68 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 71 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 72 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Debug|x86.ActiveCfg = Debug|Any CPU 73 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Release|Any CPU.ActiveCfg = Release|Any CPU 74 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Release|Any CPU.Build.0 = Release|Any CPU 75 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 76 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Release|Mixed Platforms.Build.0 = Release|Any CPU 77 | {EC21F371-D920-4485-9E87-0FFB0A114FED}.Release|x86.ActiveCfg = Release|Any CPU 78 | EndGlobalSection 79 | GlobalSection(SolutionProperties) = preSolution 80 | HideSolutionNode = FALSE 81 | EndGlobalSection 82 | GlobalSection(ExtensibilityGlobals) = postSolution 83 | SolutionGuid = {855899FD-39BF-4758-8F8E-7F773627754B} 84 | EndGlobalSection 85 | EndGlobal 86 | -------------------------------------------------------------------------------- /MatrixScreen/ChronoDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FerretLib.SFML; 3 | using SFML.Graphics; 4 | using SFML.Window; 5 | 6 | namespace MatrixScreen 7 | { 8 | internal class ChronoDisplay : IEntity 9 | { 10 | private Text _text; 11 | private Color _color; 12 | private ChronoEventArgs _chrono; 13 | 14 | public ChronoDisplay() 15 | { 16 | _text = new Text { 17 | Font = new Font(@"data\lekton.ttf"), 18 | CharacterSize = 14, 19 | Position = new Vector2f(30, 30), 20 | }; 21 | } 22 | 23 | public void Render(RenderTarget target) 24 | { 25 | _text.DisplayedString += "\nCanvas: " + target.Size.X + "x" + target.Size.Y; 26 | target.Draw(_text); 27 | } 28 | 29 | public void Update(ChronoEventArgs chronoArgs) 30 | { 31 | _chrono = chronoArgs; 32 | 33 | _text.DisplayedString = string.Format("Dδ{0:0.00000}\n{1:#####0.00}FPS", 34 | _chrono.Delta, _chrono.Fps); 35 | var x = (byte)(DateTime.Now.Millisecond % 255); 36 | _color = new Color(x,255,x); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /MatrixScreen/Debug.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using SFML.Graphics; 6 | using SFML.Window; 7 | 8 | namespace MatrixScreen 9 | { 10 | public static class Debug 11 | { 12 | private static readonly Text _text; 13 | private static readonly RectangleShape _rectangle; 14 | 15 | static Debug() 16 | { 17 | _rectangle = new RectangleShape(); 18 | 19 | _text = new Text("", new Font(@"data/lekton.ttf")) { 20 | Color = Color.Yellow, 21 | CharacterSize = 14, 22 | }; 23 | } 24 | 25 | public static void DrawRect(RenderTarget target, Color color, float x, float y, float width, float height, float originX, float originY) 26 | { 27 | _rectangle.Position = new Vector2f(x, y); 28 | _rectangle.Size = new Vector2f(width, height); 29 | _rectangle.FillColor = color; 30 | target.Draw(_rectangle, RenderStates.Default); 31 | } 32 | 33 | public static void DrawText(RenderTarget target, Color color, string text, float x, float y) 34 | { 35 | DrawText(target, color, text, new Vector2f(x, y)); 36 | } 37 | 38 | public static void DrawText(RenderTarget target, Color color, string text, Vector2f position) 39 | { 40 | _text.Position = position; 41 | _text.Color = color; 42 | _text.DisplayedString = text; 43 | _text.Draw(target, RenderStates.Default); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /MatrixScreen/DebugEngine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FerretLib.SFML; 3 | using SFML.Graphics; 4 | using SFML.Window; 5 | using Color = SFML.Graphics.Color; 6 | using Font = SFML.Graphics.Font; 7 | 8 | namespace MatrixScreen 9 | { 10 | public class DebugEngine : IWorldEngine 11 | { 12 | private ViewPortCollection _viewports; 13 | private Text text; 14 | 15 | public DebugEngine() 16 | { 17 | text = new Text 18 | { 19 | Font = new Font(@"data\lekton.ttf"), 20 | CharacterSize = 12, 21 | Color = Color.Green, 22 | }; 23 | } 24 | 25 | #region IWorldEngine 26 | public void Render(RenderTarget target) 27 | { 28 | var vertices = new[]{ 29 | new Vertex(new Vector2f(0,0), new Color(255,255,0)), 30 | new Vertex(new Vector2f(canvas.Size.X,0), new Color(255,0,0)), 31 | new Vertex(new Vector2f(canvas.Size.X,canvas.Size.Y), new Color(0,255,0)), 32 | new Vertex(new Vector2f(0,canvas.Size.Y), new Color(0,0,255)), 33 | }; 34 | 35 | var verticesInner = new[]{ 36 | new Vertex(new Vector2f(10,10), new Color(0,0,30)), 37 | new Vertex(new Vector2f(canvas.Size.X-10,10), new Color(0,0,0)), 38 | new Vertex(new Vector2f(canvas.Size.X-10,canvas.Size.Y-10), new Color(30,0,30)), 39 | new Vertex(new Vector2f(10,canvas.Size.Y-10), new Color(0,0,0)), 40 | }; 41 | canvas.Draw(vertices, PrimitiveType.Quads); 42 | canvas.Draw(verticesInner, PrimitiveType.Quads); 43 | 44 | var cursorPosition = _viewports.CursorPosition(); 45 | var globalCursorText = string.Format("Global cursor: {0}:{1}", cursorPosition.X, cursorPosition.Y); 46 | foreach (var viewport in _viewports) 47 | { 48 | text.Color = viewport.WorkingArea.Contains(Mouse.GetPosition().ToPoint()) ? 49 | Color.Green : Color.Red; 50 | 51 | text.Position = new Vector2f(30, 30); 52 | text.DisplayedString = string.Format("Cursor: {0}:{1}", Mouse.GetPosition().X, Mouse.GetPosition().Y); 53 | viewport.Window.Draw(text); 54 | 55 | text.Position = new Vector2f(30, 50); 56 | text.DisplayedString = globalCursorText; 57 | viewport.Window.Draw(text); 58 | 59 | var pos = _viewports.GetLocalCoordinates(Mouse.GetPosition(),viewport); 60 | text.Position = new Vector2f(30, 70); 61 | text.DisplayedString = string.Format("Local position: {0}:{1}", 62 | pos.X,pos.Y); 63 | viewport.Window.Draw(text); 64 | 65 | text.Position = new Vector2f(30, 90); 66 | text.DisplayedString = string.Format("Viewport #{0}; origin: {1},{2}", 67 | viewport.ID, 68 | viewport.WorkingArea.Left, 69 | viewport.WorkingArea.Top); 70 | viewport.Window.Draw(text); 71 | 72 | text.Position = new Vector2f(30, 110); 73 | text.DisplayedString = string.Format("Global boundaries: t:{0},l:{1},r:{2},b{3}", 74 | _viewports.WorkingArea.Top, 75 | _viewports.WorkingArea.Left, 76 | _viewports.WorkingArea.Right, 77 | _viewports.WorkingArea.Bottom); 78 | viewport.Window.Draw(text); 79 | 80 | viewport.Window.Display(); 81 | } 82 | } 83 | 84 | public void Update(ChronoEventArgs chronoArgs) 85 | { 86 | 87 | } 88 | 89 | void IWorldEngine.Initialise(ViewPortCollection viewports) 90 | { 91 | _viewports = viewports; 92 | } 93 | #endregion 94 | 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /MatrixScreen/MatrixEngine.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | using System.Threading; 4 | using FerretLib.SFML; 5 | using SFML.Graphics; 6 | using SFML.Window; 7 | using Color = SFML.Graphics.Color; 8 | using Font = SFML.Graphics.Font; 9 | 10 | namespace MatrixScreen 11 | { 12 | public class MatrixEngine : IWorldEngine 13 | { 14 | private List _glyphsStreams; 15 | 16 | private ChronoDisplay _chrono; 17 | private MatrixConfig _settings; 18 | 19 | public MatrixEngine(MatrixConfig settings) 20 | { 21 | _chrono = new ChronoDisplay(); 22 | _settings = settings; 23 | } 24 | 25 | public void Render(RenderTarget canvas) 26 | { 27 | ((RenderTexture)canvas).Display(); 28 | ((RenderTexture)canvas).Clear(Color.Black); 29 | _glyphsStreams.ForEach(x=>x.Render(canvas)); 30 | 31 | _chrono.Render(canvas); 32 | } 33 | 34 | public void Update(ChronoEventArgs chronoArgs) 35 | { 36 | _chrono.Update(chronoArgs); 37 | _glyphsStreams.ForEach(x=>x.Update(chronoArgs)); 38 | } 39 | 40 | void IWorldEngine.Initialise(ViewPortCollection viewports) 41 | { 42 | var area = new Vector2u( 43 | (uint)viewports.WorkingArea.Width, 44 | (uint)viewports.WorkingArea.Height); 45 | 46 | _glyphsStreams = new List(); 47 | foreach (var setting in _settings.RenderLayers) 48 | { 49 | _glyphsStreams.Add(new GlyphStreamManager(setting, area)); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MatrixScreen/MatrixEngine/Glyph.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.Net.Configuration; 4 | using FerretLib.SFML; 5 | using SFML.Graphics; 6 | using SFML.Window; 7 | 8 | namespace MatrixScreen 9 | { 10 | public class Glyph 11 | { 12 | public const int MAX_INDEX = 92; // maximum glyph character index 13 | 14 | public const int GLYPH_TEXTURE_COLUMNS = 16; 15 | public const int GLYPH_TEXTURE_ROWS = 8; 16 | 17 | public const int GLYPH_TEXTURE_SIZE = 2048; 18 | public const int GLYPH_WIDTH = GLYPH_TEXTURE_SIZE / GLYPH_TEXTURE_COLUMNS; 19 | public const int GLYPH_HEIGHT = GLYPH_TEXTURE_SIZE / GLYPH_TEXTURE_ROWS; 20 | 21 | private readonly GlyphConfig _config; 22 | 23 | private bool _isFlickering; 24 | 25 | private readonly TwitchCalculator _twitch; 26 | private readonly Sprite _sprite; 27 | private readonly Sprite _spriteOutline; 28 | private readonly IntRect _glyphArea; 29 | private static readonly Texture _texture = new Texture(@"data\glyphs.png") 30 | { 31 | Smooth = true, 32 | Repeated = false, 33 | }; 34 | private static readonly Texture _textureOutline = new Texture(@"data\glyphsOutline.png") 35 | { 36 | Smooth = true, 37 | Repeated = false, 38 | }; 39 | 40 | private int _index; 41 | private int Index 42 | { 43 | get 44 | { 45 | return _index; 46 | } 47 | set 48 | { 49 | _index = value; 50 | var x = value % GLYPH_TEXTURE_COLUMNS; 51 | var y = (value - x) / GLYPH_TEXTURE_COLUMNS; 52 | var textureRect = new IntRect( 53 | x * GLYPH_WIDTH, 54 | y * GLYPH_HEIGHT, 55 | GLYPH_WIDTH, 56 | GLYPH_HEIGHT 57 | ); 58 | 59 | _sprite.TextureRect = textureRect; 60 | _spriteOutline.TextureRect = textureRect; 61 | } 62 | } 63 | 64 | bool _isDraw = false; 65 | 66 | public Glyph(Vector2f location, float scale, GlyphConfig settings) 67 | { 68 | _config = settings; 69 | 70 | _sprite = new Sprite(_texture) 71 | { 72 | Scale = new Vector2f(scale, scale), 73 | Position = location, 74 | }; 75 | 76 | _spriteOutline = new Sprite(_textureOutline) 77 | { 78 | Scale = new Vector2f(scale, scale), 79 | Position = location, 80 | }; 81 | 82 | var glyphAreaX = (GLYPH_WIDTH*scale); 83 | _glyphArea = new IntRect( 84 | (int) (location.X - 0.5f*glyphAreaX), 85 | (int) location.Y, 86 | (int) glyphAreaX, 87 | (int) (GLYPH_HEIGHT*scale)); 88 | 89 | Index = GetRandom.Int(MAX_INDEX); 90 | _twitch = new TwitchCalculator(); 91 | } 92 | 93 | public void Render(RenderTarget target) 94 | { 95 | if (!_isDraw) return; 96 | 97 | //// TODO: refactor to a debugGlyph class 98 | //if (Config.IsDebugRendering) 99 | //{ 100 | // Debug.DrawRect(target, new Color(255, 255, 0, 30), _sprite.Position.X, 101 | // _sprite.Position.Y, _sprite.TextureRect.Width*_sprite.Scale.X, 102 | // _sprite.TextureRect.Height*_sprite.Scale.Y, 0, 0); 103 | //} 104 | 105 | _sprite.Draw(target, new RenderStates(BlendMode.Add)); 106 | _spriteOutline.Draw(target, new RenderStates(BlendMode.Alpha)); 107 | } 108 | 109 | public void Update(ChronoEventArgs chronoArgs, IntRect visibleRegion) 110 | { 111 | var modifier = GetVisibility(visibleRegion); 112 | 113 | _isDraw = modifier > 0; 114 | if(!_isDraw) return; 115 | 116 | if(GetRandom.Float(1f) < _config.ChanceOfHeavyFlicker) _isFlickering = !_isFlickering; 117 | 118 | _spriteOutline.Color = new Color(0, 0, 0, (byte)(CalculateOpacity() * 0.6f)); 119 | _sprite.Color = new Color(0, 255, 0, CalculateOpacity()); 120 | 121 | if (_twitch.IsTriggered(chronoArgs)) { 122 | Index = GetRandom.Int(MAX_INDEX); 123 | } 124 | } 125 | 126 | private byte CalculateOpacity() 127 | { 128 | return _isFlickering 129 | ? GetRandom.Byte(_config.HeavyFlickerMinAlpha, _config.HeavyFlickerMinAlpha) 130 | : GetRandom.Byte(_config.MinA, _config.MaxA); 131 | } 132 | 133 | private float GetVisibility(IntRect visibleRegion) 134 | { 135 | // Outside bounds 136 | if (visibleRegion.Top > _glyphArea.Bottom()) 137 | return 0; 138 | if (visibleRegion.Bottom() < _glyphArea.Top) 139 | return 0; 140 | 141 | // Completely within bounds 142 | if (visibleRegion.Top < _glyphArea.Top 143 | && visibleRegion.Bottom() > _glyphArea.Bottom()) 144 | return 1;; 145 | 146 | 147 | // Partially within bounds - fading out 148 | if (visibleRegion.Top > _glyphArea.Top) 149 | return (_glyphArea.Bottom() - visibleRegion.Top) / (float)(_glyphArea.Bottom() - _glyphArea.Top); 150 | 151 | 152 | // Partially within bounds - fading in 153 | return (float)(visibleRegion.Bottom() - _glyphArea.Top) / _glyphArea.Height; 154 | } 155 | } 156 | } -------------------------------------------------------------------------------- /MatrixScreen/MatrixEngine/GlyphStream.Debug.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | using FerretLib.SFML; 4 | using SFML.Graphics; 5 | using SFML.Window; 6 | 7 | namespace MatrixScreen 8 | { 9 | public class GlyphStreamDebug : IEntity 10 | { 11 | private readonly int MAX_GLYPHS; 12 | private readonly int MIN_GLYPHS; 13 | private readonly float MAX_MOVEMENTRATE; 14 | private readonly float MIN_MOVEMENTRATE; 15 | private readonly float MIN_GLYPHSCALE; 16 | private readonly float MAX_GLYPHSCALE; 17 | private readonly float MARGIN_SCALE; 18 | 19 | private readonly float movementRate; 20 | private readonly float scale; 21 | private readonly GlyphConfig _glyphConfig; 22 | private float displayDurationMultipier; // affects how long 23 | 24 | private readonly Rectangle _workingArea; 25 | 26 | private List _glyphs; 27 | 28 | // TODO: chance of glyph change; glyph index, color 29 | 30 | private Vector2f MaskPosition; // Stream position - scrolls down the screen 31 | private Vector2f GlyphPosition; // Individual glyphs location - doesn't change 32 | private IntRect GlyphArea; // Total glyph-occupied region - doesn't change 33 | 34 | public GlyphStream(GlyphStreamConfig settings, Rectangle workingArea) 35 | { 36 | _workingArea = workingArea; 37 | _glyphConfig = settings.GlyphConfig; 38 | 39 | MAX_GLYPHS = settings.MaxGlyphs; 40 | MIN_GLYPHS = settings.MinGlyphs; 41 | MAX_MOVEMENTRATE = settings.MaxMovementRate; 42 | MIN_MOVEMENTRATE = settings.MinMovementRate; 43 | MIN_GLYPHSCALE = settings.MinGlyphScale; 44 | MAX_GLYPHSCALE = settings.MaxGlyphScale; 45 | MARGIN_SCALE = settings.MarginScale; 46 | 47 | movementRate = GetRandom.Float(MIN_MOVEMENTRATE, MAX_MOVEMENTRATE); 48 | var numberOfGlyphs = GetRandom.Int(MIN_GLYPHS, MAX_GLYPHS); 49 | scale = GetRandom.Float(MIN_GLYPHSCALE, MAX_GLYPHSCALE); 50 | displayDurationMultipier = GetRandom.Float(0.5f / numberOfGlyphs, 1f); 51 | 52 | GlyphPosition = new Vector2f( 53 | GetRandom.Int((int)-GlyphSize.X, (int) (_workingArea.Width + GlyphSize.X)), 54 | GetRandom.Int((int)-GlyphSize.Y, (int)(_workingArea.Height + GlyphSize.Y))); 55 | 56 | ////TODO: refactor to a debugGlpyhStream class 57 | //if (Config.IsDebugGlyphStreams) 58 | //{ 59 | // // Just for debugging 60 | // numberOfGlyphs = 6; 61 | // GlyphPosition = new Vector2f(10,10); 62 | // movementRate = 80; 63 | // scale = 0.2f; 64 | // displayDurationMultipier = 0.5f; 65 | //} 66 | 67 | _glyphs = new List(); 68 | for (int i = 0; i < numberOfGlyphs; i++) 69 | { 70 | var y = GlyphPosition.Y + (i * Glyph.GLYPH_HEIGHT * scale * MARGIN_SCALE); 71 | 72 | if (y + Glyph.GLYPH_HEIGHT < 0) continue; 73 | if (y > workingArea.Height) continue; 74 | 75 | _glyphs.Add(new Glyph(new Vector2f(GlyphPosition.X, y), scale, _glyphConfig)); 76 | } 77 | 78 | MaskPosition = new Vector2f(GlyphPosition.X, GlyphPosition.Y - MaskSize.Y); 79 | 80 | GlyphArea = new IntRect( 81 | (int)GlyphPosition.X, 82 | (int)GlyphPosition.Y, 83 | (int)GlyphSize.X, 84 | (int)GlyphSize.Y + (int)(GlyphSize.Y * MARGIN_SCALE * (_glyphs.Count - 1f)) 85 | ); 86 | } 87 | 88 | 89 | public Vector2f MaskSize 90 | { 91 | get { return new Vector2f(GlyphSize.X, GlyphSize.Y * _glyphs.Count * displayDurationMultipier); } //TODO: handle margin scale 92 | } 93 | 94 | public Vector2f GlyphSize 95 | { 96 | get 97 | { 98 | return new Vector2f(Glyph.GLYPH_WIDTH * scale, Glyph.GLYPH_HEIGHT * scale); 99 | } 100 | } 101 | 102 | public bool IsExpired { get; private set; } 103 | 104 | public IntRect MaskArea() 105 | { 106 | return new IntRect( 107 | (int)MaskPosition.X, 108 | (int)MaskPosition.Y, 109 | (int)MaskSize.X, 110 | (int)MaskSize.Y 111 | ); 112 | } 113 | 114 | public void Render(RenderTarget canvas) 115 | { 116 | _glyphs.ForEach(g=>g.Render(canvas)); 117 | 118 | ////TODO: refactor to a debugGlyphStream class 119 | //if (Config.IsDebugRendering) // debug 120 | //{ 121 | // //Debug.DrawRect(canvas, new Color(0, 255, 0, 20), 122 | // // MaskPosition.X, MaskPosition.Y, 123 | // // MaskSize.X, MaskSize.Y, 124 | // // //Glyph.GLYPH_WIDTH * 0.5f * scale,0); 125 | // // 0,0); 126 | 127 | // Debug.DrawRect(canvas, new Color(0, 255, 255, 20), 128 | // MaskPosition.X - 5, MaskPosition.Y, 129 | // GlyphSize.X + 10, 10, 130 | // 0,5); 131 | 132 | // Debug.DrawRect(canvas, new Color(0, 255, 255, 20), 133 | // MaskPosition.X - 5, MaskPosition.Y + MaskSize.Y, 134 | // GlyphSize.X + 10, 10, 135 | // 0,5); 136 | 137 | 138 | //} 139 | } 140 | 141 | public void Update(ChronoEventArgs chronoArgs) 142 | { 143 | if (IsExpired) return; 144 | 145 | MaskPosition.Y += (float)(movementRate * chronoArgs.Delta); 146 | _glyphs.ForEach(g=>g.Update(chronoArgs, MaskArea())); 147 | 148 | CheckIfExpired(); 149 | } 150 | 151 | private void CheckIfExpired() 152 | { 153 | if (MaskPosition.Y > _workingArea.Bottom || 154 | MaskPosition.Y > GlyphPosition.Y + GlyphArea.Height) 155 | { 156 | IsExpired = true; 157 | } 158 | } 159 | } 160 | } -------------------------------------------------------------------------------- /MatrixScreen/MatrixEngine/GlyphStream.Noise.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | using FerretLib.SFML; 4 | using SFML.Graphics; 5 | using SFML.Window; 6 | 7 | namespace MatrixScreen 8 | { 9 | /// 10 | /// Not what I intended but looks cool enough to keep to maybe work in later 11 | /// 12 | public class GlyphStreamNoise : IEntity 13 | { 14 | private readonly float _movementRate; 15 | private readonly float _scale; 16 | 17 | private readonly Rectangle _workingArea; 18 | private readonly List _glyphs; 19 | private readonly Vector2f _maskSize; 20 | 21 | private Vector2f MaskPosition; // Stream position - scrolls down the screen 22 | private Vector2f GlyphPosition; // Individual glyphs location - doesn't change 23 | private IntRect GlyphArea; // Total glyph-occupied region - doesn't change 24 | 25 | public bool IsExpired { get; private set; } 26 | 27 | public GlyphStreamNoise(GlyphStreamConfig settings, Rectangle workingArea) 28 | { 29 | _glyphs = new List(); 30 | _workingArea = workingArea; 31 | 32 | _movementRate = GetRandom.Float(settings.MinMovementRate, settings.MaxMovementRate); 33 | _scale = GetRandom.Float(settings.MinGlyphScale, settings.MaxGlyphScale); 34 | var glyphCount = GetRandom.Int(settings.MinGlyphs, settings.MaxGlyphs); 35 | float displayDurationMultipier = GetRandom.Float(0.5f, 2f); 36 | 37 | var glyphSize = new Vector2f(Glyph.GLYPH_WIDTH * _scale, Glyph.GLYPH_HEIGHT * _scale); 38 | 39 | _maskSize = new Vector2f(glyphSize.X, glyphSize.Y * _glyphs.Count * displayDurationMultipier); // TODO: incorporate margin 40 | 41 | GlyphPosition = new Vector2f( 42 | GetRandom.Int((int)-glyphSize.X, (int)(_workingArea.Width + glyphSize.X)), 43 | GetRandom.Int((int)-glyphSize.Y, (int)(_workingArea.Height + glyphSize.Y))); 44 | 45 | GlyphArea = new IntRect( 46 | (int)GlyphPosition.X, 47 | (int)GlyphPosition.Y, 48 | (int)glyphSize.X, 49 | (int)glyphSize.Y + (int)(glyphSize.Y * settings.MarginScale * (_glyphs.Count - 1f)) 50 | ); 51 | 52 | for (int i = 0; i < glyphCount; i++) 53 | { 54 | var y = GlyphPosition.Y + (i * Glyph.GLYPH_HEIGHT * _scale * settings.MarginScale); 55 | 56 | if (y + Glyph.GLYPH_HEIGHT < 0) continue; 57 | if (y > workingArea.Height) continue; 58 | 59 | _glyphs.Add(new Glyph(new Vector2f(GlyphPosition.X, y), _scale, settings.GlyphConfig)); 60 | } 61 | 62 | MaskPosition = new Vector2f(GlyphPosition.X, GlyphPosition.Y - _maskSize.Y); 63 | } 64 | 65 | private IntRect MaskArea() 66 | { 67 | return new IntRect( 68 | (int)MaskPosition.X, 69 | (int)MaskPosition.Y, 70 | (int)_maskSize.X, 71 | (int)_maskSize.Y 72 | ); 73 | } 74 | 75 | public void Render(RenderTarget canvas) 76 | { 77 | _glyphs.ForEach(g => g.Render(canvas)); 78 | } 79 | 80 | public void Update(ChronoEventArgs chronoArgs) 81 | { 82 | if (IsExpired) return; 83 | 84 | MaskPosition.Y += (float)(_movementRate * chronoArgs.Delta); 85 | _glyphs.ForEach(g => g.Update(chronoArgs, MaskArea())); 86 | 87 | CheckIfExpired(); 88 | } 89 | 90 | private void CheckIfExpired() 91 | { 92 | if (MaskPosition.Y > _workingArea.Bottom || 93 | MaskPosition.Y > GlyphPosition.Y + GlyphArea.Height) 94 | { 95 | IsExpired = true; 96 | } 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /MatrixScreen/MatrixEngine/GlyphStream.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | using FerretLib.SFML; 4 | using SFML.Graphics; 5 | using SFML.Window; 6 | 7 | namespace MatrixScreen 8 | { 9 | public class GlyphStream : IEntity 10 | { 11 | private readonly float _movementRate; 12 | private readonly float _scale; 13 | 14 | private readonly Rectangle _workingArea; 15 | private readonly List _glyphs; 16 | private readonly Vector2f _maskSize; 17 | 18 | private Vector2f MaskPosition; // Stream position - scrolls down the screen 19 | private Vector2f GlyphPosition; // Individual glyphs location - doesn't change 20 | private IntRect GlyphArea; // Total glyph-occupied region - doesn't change 21 | 22 | public bool IsExpired { get; private set; } 23 | 24 | public GlyphStream(GlyphStreamConfig settings, Rectangle workingArea) 25 | { 26 | _glyphs = new List(); 27 | _workingArea = workingArea; 28 | 29 | _movementRate = GetRandom.Float(settings.MinMovementRate, settings.MaxMovementRate); 30 | _scale = GetRandom.Float(settings.MinGlyphScale, settings.MaxGlyphScale); 31 | var glyphCount = GetRandom.Int(settings.MinGlyphs, settings.MaxGlyphs); 32 | float displayDurationMultipier = GetRandom.Float(0.5f, 2f); 33 | 34 | var glyphSize = new Vector2f(Glyph.GLYPH_WIDTH * _scale, Glyph.GLYPH_HEIGHT * _scale); 35 | 36 | GlyphPosition = new Vector2f( 37 | GetRandom.Int((int)-glyphSize.X, (int)(_workingArea.Width + glyphSize.X)), 38 | GetRandom.Int((int)-glyphSize.Y, (int)(_workingArea.Height + glyphSize.Y))); 39 | 40 | GlyphArea = new IntRect( 41 | (int)GlyphPosition.X, 42 | (int)GlyphPosition.Y, 43 | (int)glyphSize.X, 44 | (int)glyphSize.Y + (int)(glyphSize.Y * settings.MarginScale * (_glyphs.Count - 1f)) 45 | ); 46 | 47 | for (int i = 0; i < glyphCount; i++) 48 | { 49 | var y = GlyphPosition.Y + (i * Glyph.GLYPH_HEIGHT * _scale * settings.MarginScale); 50 | 51 | if (y + Glyph.GLYPH_HEIGHT < 0) continue; 52 | if (y > workingArea.Height) continue; 53 | 54 | _glyphs.Add(new Glyph(new Vector2f(GlyphPosition.X, y), _scale, settings.GlyphConfig)); 55 | } 56 | 57 | _maskSize = new Vector2f(glyphSize.X, glyphSize.Y * _glyphs.Count * displayDurationMultipier); // TODO: incorporate margin 58 | MaskPosition = new Vector2f(GlyphPosition.X, GlyphPosition.Y - _maskSize.Y); 59 | } 60 | 61 | private IntRect MaskArea() 62 | { 63 | return new IntRect( 64 | (int)MaskPosition.X, 65 | (int)MaskPosition.Y, 66 | (int)_maskSize.X, 67 | (int)_maskSize.Y 68 | ); 69 | } 70 | 71 | public void Render(RenderTarget canvas) 72 | { 73 | _glyphs.ForEach(g => g.Render(canvas)); 74 | } 75 | 76 | public void Update(ChronoEventArgs chronoArgs) 77 | { 78 | if (IsExpired) return; 79 | 80 | MaskPosition.Y += (float)(_movementRate * chronoArgs.Delta); 81 | _glyphs.ForEach(g => g.Update(chronoArgs, MaskArea())); 82 | 83 | CheckIfExpired(); 84 | } 85 | 86 | private void CheckIfExpired() 87 | { 88 | if (MaskPosition.Y > _workingArea.Bottom || 89 | MaskPosition.Y > GlyphPosition.Y + GlyphArea.Height) 90 | { 91 | IsExpired = true; 92 | } 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /MatrixScreen/MatrixEngine/GlyphStreamManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | using System.Linq; 4 | using FerretLib.SFML; 5 | using Microsoft.Win32.SafeHandles; 6 | using SFML.Graphics; 7 | using SFML.Window; 8 | using Color = SFML.Graphics.Color; 9 | 10 | namespace MatrixScreen 11 | { 12 | public class GlyphStreamManager : IEntity 13 | { 14 | private readonly int _maximumStreams; 15 | private readonly float _chanceOfNewStream; 16 | private readonly float NEW_STREAM_CHECK_FREQUENCY = 0.016f; // TODO: config 17 | private readonly GlyphStreamManagerConfig _settings; 18 | private readonly RenderTexture tempCanvas; 19 | private readonly ShaderWrapper shader; 20 | 21 | private readonly Rectangle _workingArea; 22 | private List streams; 23 | private double _runningDelta; 24 | 25 | public GlyphStreamManager(GlyphStreamManagerConfig settings, Vector2u workingArea) 26 | { 27 | _workingArea = workingArea.ToRectangle(); 28 | streams = new List(); 29 | _settings = settings; 30 | 31 | if (!string.IsNullOrEmpty(settings.ShaderType)) // TODO: configurable shader 32 | { 33 | shader = ShaderWrapper.Get(settings.ShaderType); 34 | tempCanvas = new RenderTexture(workingArea.X, workingArea.Y, true); 35 | tempCanvas.Display(); 36 | } 37 | 38 | _maximumStreams = settings.MaximumGlyphStreams; 39 | _chanceOfNewStream = settings.ChanceOfNewGlyphStream; 40 | } 41 | 42 | private void AddNewGlyphStream() 43 | { 44 | streams.Add(new GlyphStream(_settings.GlyphStreamConfig, _workingArea)); 45 | } 46 | 47 | public void Render(RenderTarget canvas) 48 | { 49 | if (shader != null) 50 | { 51 | tempCanvas.Clear(new Color(0,0,0,0)); 52 | streams.ForEach(x => x.Render(tempCanvas)); 53 | canvas.Draw(new Sprite(tempCanvas.Texture), shader.Bind(tempCanvas)); 54 | } 55 | else 56 | { 57 | streams.ForEach(x => x.Render(canvas)); 58 | } 59 | } 60 | 61 | public void Update(ChronoEventArgs chronoArgs) 62 | { 63 | if(shader != null) shader.Update(chronoArgs); 64 | UpdateStreams(chronoArgs); 65 | PurgeOldStreams(); 66 | AddNewStreams(chronoArgs); 67 | } 68 | 69 | private void UpdateStreams(ChronoEventArgs chronoArgs) 70 | { 71 | streams.ForEach(x => x.Update(chronoArgs)); 72 | } 73 | 74 | private void PurgeOldStreams() 75 | { 76 | streams = streams.Where(x => !x.IsExpired).ToList(); 77 | } 78 | 79 | private void AddNewStreams(ChronoEventArgs chronoArgs) 80 | { 81 | _runningDelta += chronoArgs.Delta; 82 | 83 | if (_runningDelta >= NEW_STREAM_CHECK_FREQUENCY) 84 | { 85 | var outcome = GetRandom.Double(0, _runningDelta); 86 | var chance = _chanceOfNewStream; 87 | while (streams.Count <= _maximumStreams && outcome < chance) 88 | { 89 | chance -= NEW_STREAM_CHECK_FREQUENCY; 90 | AddNewGlyphStream(); 91 | } 92 | 93 | _runningDelta -= NEW_STREAM_CHECK_FREQUENCY; 94 | } 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /MatrixScreen/MatrixEngine/ShaderWrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FerretLib.SFML; 3 | using SFML.Graphics; 4 | using SFML.Window; 5 | 6 | namespace MatrixScreen 7 | { 8 | public abstract class ShaderWrapper 9 | { 10 | public Shader Shader { get; protected set; } 11 | public abstract RenderStates Bind(RenderTexture canvas); 12 | protected ChronoEventArgs chronoEvent; 13 | 14 | public static ShaderWrapper Get(string type) 15 | { 16 | if (type.ToUpperInvariant() == GlyphStreamManagerConfig.SHADER_GLITCH) return new GlitchShader(); 17 | if (type.ToUpperInvariant() == GlyphStreamManagerConfig.SHADER_GHOST) return new GhostShader(); 18 | return null; 19 | } 20 | 21 | public void Update(ChronoEventArgs args) 22 | { 23 | chronoEvent = args; 24 | } 25 | 26 | private class GlitchShader : ShaderWrapper 27 | { 28 | private double nextTick; 29 | private double tickDuration; 30 | 31 | public GlitchShader() 32 | { 33 | Shader = new Shader(null, @"data/frag.c"); 34 | Tick(0); 35 | } 36 | 37 | private void Tick(double monotonic) 38 | { 39 | nextTick = monotonic + GetRandom.Double(0.8, 3); // TODO - change to much higher max value 40 | tickDuration = monotonic + GetRandom.Double(0.01, 0.07f); 41 | } 42 | 43 | 44 | public override RenderStates Bind(RenderTexture canvas) 45 | { 46 | var result = RenderStates.Default; 47 | 48 | if (chronoEvent.Monotonic > nextTick) 49 | { 50 | Tick(chronoEvent.Monotonic); 51 | } 52 | 53 | var milliseconds = tickDuration - chronoEvent.Monotonic; 54 | if (milliseconds > 0) 55 | { 56 | Shader.SetParameter("texture", canvas.Texture); 57 | Shader.SetParameter("sigma", 2); 58 | Shader.SetParameter("glowMultiplier", 800); 59 | Shader.SetParameter("width", (float)((1 - milliseconds)* 1000f) * (float)milliseconds * 2f); // 1 = horizontal lines, up to around 1000 is good 60 | result.Shader = Shader; 61 | } 62 | return result; 63 | } 64 | } 65 | 66 | private class GhostShader : ShaderWrapper 67 | { 68 | private double nextTick; 69 | private double tickDuration; 70 | 71 | public GhostShader() 72 | { 73 | Shader = new Shader(null, @"data/frag.c"); 74 | Tick(0); 75 | } 76 | 77 | private void Tick(double monotonic) 78 | { 79 | nextTick = monotonic + GetRandom.Double(0.8, 3); // TODO - change to much higher max value 80 | tickDuration = monotonic + GetRandom.Double(0.01, 0.07f); 81 | } 82 | 83 | 84 | public override RenderStates Bind(RenderTexture canvas) 85 | { 86 | var result = RenderStates.Default; 87 | 88 | if (chronoEvent.Monotonic > nextTick) 89 | { 90 | Tick(chronoEvent.Monotonic); 91 | } 92 | 93 | var milliseconds = tickDuration - chronoEvent.Monotonic; 94 | if (milliseconds > 0) 95 | { 96 | Shader.SetParameter("texture", canvas.Texture); 97 | Shader.SetParameter("sigma", Mouse.GetPosition().X); 98 | Shader.SetParameter("glowMultiplier", 800); 99 | Shader.SetParameter("width", Mouse.GetPosition().Y * 0.3f); 100 | result.Shader = Shader; 101 | } 102 | return result; 103 | } 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /MatrixScreen/MatrixEngine/TwitchCalculator.cs: -------------------------------------------------------------------------------- 1 | using FerretLib.SFML; 2 | 3 | namespace MatrixScreen 4 | { 5 | public class TwitchCalculator 6 | { 7 | private const float MINIMUM_TWITCH_FREQUENCY = 0.06f; 8 | private const float MAXIMUM_TWITCH_FREQUENCY = 20f; 9 | 10 | private double _secondsCounter; 11 | 12 | private float _twitchFrequency; 13 | private float _minTwitchFrequency; 14 | private float _maxTwitchFrequency; 15 | private float _chanceOfTrigger; 16 | 17 | private readonly bool _changeFrequencyOnTrigger = GetRandom.Bool(0.1f); 18 | 19 | public TwitchCalculator() 20 | { 21 | UpdateTriggerFrequency(true); 22 | 23 | if (_minTwitchFrequency > _maxTwitchFrequency) 24 | { 25 | var swap = _minTwitchFrequency; 26 | _minTwitchFrequency = _maxTwitchFrequency; 27 | _maxTwitchFrequency = swap; 28 | } 29 | } 30 | 31 | private void UpdateTriggerFrequency(bool force = false) 32 | { 33 | if (force || _changeFrequencyOnTrigger) 34 | { 35 | _minTwitchFrequency = GetRandom.Float(MINIMUM_TWITCH_FREQUENCY, MAXIMUM_TWITCH_FREQUENCY); 36 | _maxTwitchFrequency = GetRandom.Float(MINIMUM_TWITCH_FREQUENCY, MAXIMUM_TWITCH_FREQUENCY); 37 | _chanceOfTrigger = GetRandom.Float(0.05f, 0.95f); 38 | } 39 | _twitchFrequency = GetRandom.Float(_minTwitchFrequency, _maxTwitchFrequency); 40 | } 41 | 42 | public bool IsTriggered(ChronoEventArgs chrono) 43 | { 44 | _secondsCounter += chrono.Delta; 45 | 46 | if (_secondsCounter > _twitchFrequency) 47 | { 48 | if (GetRandom.Bool(_chanceOfTrigger)) 49 | { 50 | _secondsCounter -= _twitchFrequency; 51 | UpdateTriggerFrequency(); 52 | return true; 53 | } 54 | } 55 | 56 | return false; 57 | } 58 | 59 | } 60 | } -------------------------------------------------------------------------------- /MatrixScreen/MatrixScreen.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {518695B2-F450-4CC1-9E8F-DDCE94C3DEF9} 9 | WinExe 10 | Properties 11 | MatrixScreen 12 | MatrixScreen.UI 13 | v3.5 14 | Client 15 | 512 16 | ..\ 17 | true 18 | publish\ 19 | true 20 | Disk 21 | false 22 | Foreground 23 | 7 24 | Days 25 | false 26 | false 27 | true 28 | 0 29 | 1.0.0.%2a 30 | false 31 | false 32 | true 33 | 34 | 35 | 36 | 37 | x86 38 | true 39 | full 40 | false 41 | bin\Debug\ 42 | DEBUG;TRACE 43 | prompt 44 | 4 45 | 46 | 47 | x86 48 | pdbonly 49 | true 50 | bin\Release\ 51 | TRACE 52 | prompt 53 | 4 54 | 55 | 56 | 57 | 58 | 59 | 60 | False 61 | ..\packages\SFML.Net.2.1.5\lib\sfmlnet-audio-2.dll 62 | 63 | 64 | ..\packages\SFML.Net.2.1.5\lib\sfmlnet-graphics-2.dll 65 | 66 | 67 | False 68 | ..\packages\SFML.Net.2.1.5\lib\sfmlnet-window-2.dll 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | {A8A5B3D5-9042-453C-81C7-C66A66F79855} 93 | FerretLib.SFML 94 | 95 | 96 | {ec21f371-d920-4485-9e87-0ffb0a114fed} 97 | MatrixScreen.Core 98 | 99 | 100 | 101 | 102 | data\glyphs.png 103 | Always 104 | 105 | 106 | data\glyphsOutline.png 107 | Always 108 | 109 | 110 | PreserveNewest 111 | 112 | 113 | PreserveNewest 114 | 115 | 116 | data\lekton.ttf 117 | Always 118 | 119 | 120 | 121 | 122 | 123 | 124 | False 125 | .NET Framework 3.5 SP1 Client Profile 126 | false 127 | 128 | 129 | False 130 | .NET Framework 3.5 SP1 131 | true 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 140 | 141 | 142 | 143 | 150 | -------------------------------------------------------------------------------- /MatrixScreen/MatrixScreen.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | False 3 | True -------------------------------------------------------------------------------- /MatrixScreen/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using FerretLib.SFML; 3 | 4 | namespace MatrixScreen 5 | { 6 | public class Program 7 | { 8 | 9 | private static void Main(string[] args) 10 | { 11 | if (args.Length > 0) 12 | { 13 | if (args[0].ToUpperInvariant().StartsWith(@"/C")) 14 | { 15 | // TODO: config 16 | return; 17 | } 18 | 19 | if (args[0].ToUpperInvariant().StartsWith(@"/P")) 20 | { 21 | // TODO: preview 22 | return; 23 | } 24 | } 25 | 26 | var settings = ConfigProvider.GetDebugConfig(); 27 | var engineSettings = new ScreenSaverSettings() { 28 | IsFullscreen = settings.IsFullscreen, 29 | IsMultiMonitorEnabled = settings.IsMultipleMonitorEnabled, 30 | MaxFps = settings.FpsLimit, 31 | }; 32 | 33 | var screenSaver = new ScreenSaverEngine(engineSettings); 34 | screenSaver.Engine = new MatrixEngine(settings); 35 | screenSaver.BindEscapeToExit(); 36 | screenSaver.Run(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MatrixScreen/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MatrixScreen")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MatrixScreen")] 13 | [assembly: AssemblyCopyright("2014 Nathan Chere")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8bc94aea-b313-4c74-b059-89d708614c99")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.*")] 36 | [assembly: AssemblyFileVersion("1")] 37 | -------------------------------------------------------------------------------- /MatrixScreen/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /MatrixScreen/data/frag.c: -------------------------------------------------------------------------------- 1 | uniform sampler2D texture; 2 | uniform float pixel_threshold; 3 | 4 | uniform float sigma; 5 | uniform float glowMultiplier; 6 | uniform float width; 7 | 8 | const int KERNEL_SIZE = 5; 9 | float glow = glowMultiplier / (sigma * sqrt(2.0 * 3.14159)); 10 | 11 | float blurWeight(float x) 12 | { 13 | return (glow * exp(-(x*x) / (2.0 * sigma * sigma))); 14 | } 15 | 16 | void main() 17 | { 18 | vec4 color = vec4(0.0); 19 | vec2 texCoord = gl_TexCoord[0].xy; 20 | 21 | for (int i = -KERNEL_SIZE; i <= KERNEL_SIZE; i++) 22 | { 23 | texCoord.x = gl_TexCoord[0].x + (i / width); 24 | color += texture2D(texture, texCoord) * blurWeight(i); 25 | } 26 | 27 | gl_FragColor = color; 28 | } 29 | 30 | //uniform sampler2D texture; 31 | //uniform float pixel_threshold; 32 | // 33 | //void main() 34 | //{ 35 | // float factor = 1.0 / (pixel_threshold + 0.001); 36 | // vec2 pos = floor(gl_TexCoord[0].xy * factor + 0.5) / factor; 37 | // gl_FragColor = texture2D(texture, pos) * gl_Color; 38 | //} -------------------------------------------------------------------------------- /MatrixScreen/data/vert.c: -------------------------------------------------------------------------------- 1 | uniform float wave_phase; 2 | uniform vec2 wave_amplitude; 3 | 4 | void main() 5 | { 6 | vec4 vertex = gl_Vertex; 7 | vertex.x += cos(gl_Vertex.y * 0.02 + wave_phase * 3.8) * wave_amplitude.x 8 | + sin(gl_Vertex.y * 0.02 + wave_phase * 6.3) * wave_amplitude.x * 0.3; 9 | vertex.y += sin(gl_Vertex.x * 0.02 + wave_phase * 2.4) * wave_amplitude.y 10 | + cos(gl_Vertex.x * 0.02 + wave_phase * 5.2) * wave_amplitude.y * 0.3; 11 | 12 | gl_Position = gl_ModelViewProjectionMatrix * vertex; 13 | gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; 14 | gl_FrontColor = gl_Color; 15 | } 16 | -------------------------------------------------------------------------------- /MatrixScreen/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Resources/glyphs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Resources/glyphs.png -------------------------------------------------------------------------------- /Resources/glyphsOutline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Resources/glyphsOutline.png -------------------------------------------------------------------------------- /Resources/lekton.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanchere/MatrixSaver/113e60b353bc94766bb442572c882e8c0379cbe7/Resources/lekton.ttf -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | Lekton (font): SIL Open Font License 2 | http://www.google.com/fonts/specimen/Lekton 3 | 4 | SFML.NET: zlib/png License 5 | http://www.sfml-dev.org/license.php 6 | 7 | MatrixSaver: 8 | Source code is free to do whatever you like with this, subject only to the 9 | limitations of the above licenses and the relevant laws in your particular 10 | jurisdiction. 11 | 12 | ============================= 13 | LICENSE EXTERNAL REFERENCES 14 | ============================= 15 | 16 | SIL Open Font License: http://scripts.sil.org/OFL 17 | zlib/png License: http://opensource.org/licenses/Zlib 18 | -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # MatrixSaver 2 | 3 | ### A completely unoriginal name for a completely unoriginal product 4 | 5 | In short: my take on the "digital rain" effect made famous by The Matrix. Heavy lifting handled by [SFML](http://www.sfml-dev.org). 6 | 7 | The main itch being scratched here is multi-monitor support. Why is it so hard to find good screensavers with good multiple monitor support (and performance)? For fellow developers the main point of interest here would be as an example of SFML.Net in the 'real world'. 8 | 9 | ## Status 10 | 11 | I am in the process of sorting through my repos, culling the ones which have succumbed to disinterest and/or code rot, and migrating the remainder to GitLab. 12 | 13 | This sits in limbo between those two states. As of August 2018 I haven't gotten around to fixing some bugs preventing it from working out-of-the-box so it remains on GitHub for now. 14 | 15 | ## Credits / thanks 16 | 17 | * Laurent Gomila: for the underlying [SFML](http://www.sfml-dev.org/) library and the SFML.Net wrapper --------------------------------------------------------------------------------