├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── TrueColorConsole.sln ├── TrueColorConsole.sln.DotSettings ├── TrueColorConsole ├── ConsoleModeInput.cs ├── ConsoleModeOutput.cs ├── TrueColorConsole.csproj ├── VTCharSet.cs ├── VTConsole.cs ├── VTConsoleCursor.cs ├── VTConsoleInputSequences.cs ├── VTConsoleMisc.cs ├── VTConsoleModeChanges.cs ├── VTConsoleQueryState.cs ├── VTConsoleTabs.cs ├── VTConsoleTextModification.cs ├── VTConsoleViewport.cs ├── VTCursorKey.cs ├── VTCursorKeysMode.cs ├── VTDecLine.cs ├── VTEraseMode.cs ├── VTFormat.cs ├── VTKey.cs └── VTKeypadMode.cs ├── TrueColorConsoleApp ├── Plasma.cs ├── Program.cs └── TrueColorConsoleApp.csproj ├── example1.png ├── example2.png ├── example3.png ├── example3.webm └── icon.png /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Aybe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TrueColorConsole 2 | 3 | 24-bit coloring and VT features for .NET System.Console ! 4 | 5 | [![NuGet](https://img.shields.io/badge/nuget-v1.0.2-blue.svg)](https://www.nuget.org/packages/TrueColorConsole/) 6 | 7 | ## Synopsis 8 | 9 | The feature was announced in [24-bit Color in the Windows Console!](https://blogs.msdn.microsoft.com/commandline/2016/09/22/24-bit-color-in-the-windows-console/), now you too can enjoy it in your .NET console app. 10 | 11 | Additionally, a high-throughput mode has been implemented for demanding apps (see gallery). 12 | 13 | ## Gallery 14 | 15 | ![](https://github.com/aybe/TrueColorConsole/raw/master/example1.png) 16 | 17 | 18 | ![](https://github.com/aybe/TrueColorConsole/raw/master/example3.png) 19 | 20 | [Watch a video of the above plasma running at 50 FPS in the console :)](https://github.com/aybe/TrueColorConsole/raw/master/example3.webm) 21 | 22 | (if your browser fails to play it, download it and use something like VLC) 23 | 24 | ## Notes 25 | 26 | See the [official docs](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) for complete reference. 27 | 28 | Modifiers for input sequences have not been implemented, yet. 29 | 30 | Basic functionality has been tested, advanced VT features haven't been. 31 | 32 | The `VTConsole` class enables the features along a few helper methods for settings color and such, but it does not wrap `Console` class entirely as it's pretty big. Actually you won't need at all to change your existing code based on `Console`, just invoke `VTConsole` functions you need before/after your calls to regular console, e.g. set a 24-bit color with `VTConsole` and write formatted lines with `Console`. 33 | 34 | ## Contribute 35 | 36 | What you can do: 37 | 38 | Share with us a link to your website showing your slick console-based game or any other type of application leveraging VT features, we'll add it here. 39 | 40 | The public API could be extended, especially the `Write...` methods as currently only overloads with `string` are available. We therefore decided to keep it slim for the time being and at the same time not push users to deprecate `Console` which is absolutely not. Feedback and time will tell as on the where public API will go, you can open an issue and discuss about the subject. 41 | 42 | Report bugs, ensure that the behavior you're encountering is not intentional by checking the official docs first. 43 | 44 | ## Credits 45 | 46 | plasma code taken from [libcaca](http://caca.zoy.org/wiki/libcaca) 47 | 48 | ## Changes 49 | 50 | 1.0.2 51 | - better readme and description 52 | 53 | 1.0.1 54 | 55 | - full docs 56 | - optimization and fixes 57 | - all formatting features but [Foreground|Background]Extended, these are as simpler to use helper methods 58 | - support of non Win10 Anniversary Update systems 59 | -------------------------------------------------------------------------------- /TrueColorConsole.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2010 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrueColorConsole", "TrueColorConsole\TrueColorConsole.csproj", "{686E75C7-3177-4AD8-BFFD-EF4F0722E4ED}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrueColorConsoleApp", "TrueColorConsoleApp\TrueColorConsoleApp.csproj", "{6035F1D9-AA28-46F6-A125-72FD09F1CE0C}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {686E75C7-3177-4AD8-BFFD-EF4F0722E4ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {686E75C7-3177-4AD8-BFFD-EF4F0722E4ED}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {686E75C7-3177-4AD8-BFFD-EF4F0722E4ED}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {686E75C7-3177-4AD8-BFFD-EF4F0722E4ED}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {6035F1D9-AA28-46F6-A125-72FD09F1CE0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {6035F1D9-AA28-46F6-A125-72FD09F1CE0C}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {6035F1D9-AA28-46F6-A125-72FD09F1CE0C}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {6035F1D9-AA28-46F6-A125-72FD09F1CE0C}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {E34E6E93-9B3C-4BE6-8251-B8C44415E494} 30 | EndGlobalSection 31 | GlobalSection(Performance) = preSolution 32 | HasPerformanceSessions = true 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /TrueColorConsole.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | BEL 3 | DEL 4 | ESC 5 | SUB 6 | VT -------------------------------------------------------------------------------- /TrueColorConsole/ConsoleModeInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics.CodeAnalysis; 3 | 4 | namespace TrueColorConsole 5 | { 6 | [Flags] 7 | [SuppressMessage("ReSharper", "UnusedMember.Global")] 8 | internal enum ConsoleModeInput : uint 9 | { 10 | EnableProcessedInput = 0x1, 11 | EnableLineInput = 0x2, 12 | EnableEchoInput = 0x4, 13 | EnableWindowInput = 0x8, 14 | EnableMouseInput = 0x10, 15 | EnableInsertMode = 0x20, 16 | EnableQuickEditMode = 0x40, 17 | EnableExtendedFlags = 0x80, 18 | EnableAutoPosition = 0x100, 19 | EnableVirtualTerminalInput = 0x200 20 | } 21 | } -------------------------------------------------------------------------------- /TrueColorConsole/ConsoleModeOutput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics.CodeAnalysis; 3 | 4 | namespace TrueColorConsole 5 | { 6 | [Flags] 7 | [SuppressMessage("ReSharper", "UnusedMember.Global")] 8 | internal enum ConsoleModeOutput : uint 9 | { 10 | EnableProcessedOutput = 0x1, 11 | EnableWrapAtEolOutput = 0x2, 12 | EnableVirtualTerminalProcessing = 0x4, 13 | DisableNewlineAutoReturn = 0x8, 14 | EnableLvbGridWorldwide = 0x10 15 | } 16 | } -------------------------------------------------------------------------------- /TrueColorConsole/TrueColorConsole.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | TrueColorConsole 6 | 1.0.2 7 | Aybe 8 | 24-bit coloring and VT features for .NET System.Console ! 9 | Better README and description. 10 | Copyright 2017 (c) Aybe 11 | console virtual terminal 24-bit true color RGB .NET VT100 12 | true 13 | https://github.com/aybe/TrueColorConsole/raw/master/icon.png 14 | https://github.com/aybe/TrueColorConsole 15 | https://raw.githubusercontent.com/aybe/TrueColorConsole/master/LICENSE 16 | true 17 | 18 | 19 | 20 | bin\Release\netstandard2.0\TrueColorConsole.xml 21 | 22 | 23 | 24 | bin\Debug\netstandard2.0\TrueColorConsole.xml 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /TrueColorConsole/VTCharSet.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace TrueColorConsole 4 | { 5 | 6 | /// 7 | /// Defines the character that is currently in use. 8 | /// 9 | [PublicAPI] 10 | public enum VTCharSet 11 | { 12 | /// 13 | /// Designate Character Set – US ASCII. 14 | /// 15 | Ascii, 16 | 17 | /// 18 | /// Designate Character Set – DEC Line Drawing. 19 | /// 20 | DecLineDrawing 21 | } 22 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTConsole.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using JetBrains.Annotations; 6 | 7 | namespace TrueColorConsole 8 | { 9 | /// 10 | /// Represents a wrapper of virtual terminal sequences for , see 11 | /// https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences for more details. 12 | /// 13 | public static partial class VTConsole 14 | { 15 | #region Interop 16 | 17 | private const uint StdOutputHandle = unchecked((uint) -11); 18 | private const uint StdInputHandle = unchecked((uint) -10); 19 | private static readonly IntPtr InvalidHandleValue = new IntPtr(-1); 20 | 21 | [DllImport("kernel32.dll", SetLastError = true)] 22 | private static extern IntPtr GetStdHandle(uint nStdHandle); 23 | 24 | [DllImport("kernel32.dll", SetLastError = true)] 25 | [return: MarshalAs(UnmanagedType.Bool)] 26 | private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); 27 | 28 | private static bool GetConsoleMode(IntPtr hConsoleHandle, out ConsoleModeOutput mode) 29 | { 30 | if (!GetConsoleMode(hConsoleHandle, out uint lpMode)) 31 | { 32 | mode = 0; 33 | return false; 34 | } 35 | 36 | mode = (ConsoleModeOutput) lpMode; 37 | return true; 38 | } 39 | 40 | private static bool GetConsoleMode(IntPtr hConsoleHandle, out ConsoleModeInput mode) 41 | { 42 | if (!GetConsoleMode(hConsoleHandle, out uint lpMode)) 43 | { 44 | mode = 0; 45 | return false; 46 | } 47 | 48 | mode = (ConsoleModeInput) lpMode; 49 | return true; 50 | } 51 | 52 | [DllImport("kernel32.dll", SetLastError = true)] 53 | [return: MarshalAs(UnmanagedType.Bool)] 54 | private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); 55 | 56 | [DllImport("kernel32.dll", SetLastError = true)] 57 | [return: MarshalAs(UnmanagedType.Bool)] 58 | private static extern bool WriteConsole( 59 | IntPtr hConsoleOutput, 60 | [MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer, 61 | int lpNumberOfCharsToWrite, 62 | out int lpNumberOfCharsToWritten, 63 | IntPtr lpReserved 64 | ); 65 | 66 | private static bool GetStdIn(out IntPtr handle) 67 | { 68 | handle = GetStdHandle(StdInputHandle); 69 | return handle != InvalidHandleValue; 70 | } 71 | 72 | private static bool GetStdOut(out IntPtr handle) 73 | { 74 | handle = GetStdHandle(StdOutputHandle); 75 | return handle != InvalidHandleValue; 76 | } 77 | 78 | #endregion 79 | 80 | #region General 81 | 82 | private const string ESC = "\x1b"; 83 | private const string BEL = "\x07"; 84 | private const string SUB = "\x1a"; 85 | private const string DEL = "\x7f"; 86 | 87 | private static readonly string[] BytesMap = 88 | Enumerable.Range(0, 256).Select(s => s.ToString()).ToArray(); 89 | 90 | private static IntPtr _inHandle; 91 | private static ConsoleModeInput _inLast; 92 | private static IntPtr _outHandle; 93 | private static ConsoleModeOutput _outLast; 94 | 95 | /// 96 | /// Gets if virtual terminal features are enabled. 97 | /// 98 | [PublicAPI] 99 | public static bool IsEnabled { get; private set; } 100 | 101 | /// 102 | /// Gets if virtual terminal features are supported (see Remarks). 103 | /// 104 | /// 105 | /// This property will return true if all features are supported, which requires Windows 10 Anniversary 106 | /// Update. If it fails, you can try to enable it manually with and passing false, and see 107 | /// whether your system supports virtual terminal sequences without features specific to Windows 10 Anniversary Update. 108 | /// 109 | [PublicAPI] 110 | public static bool IsSupported { get; } = Enable() && Disable(); 111 | 112 | /// 113 | /// Gets the handle to the console standard input. 114 | /// 115 | [PublicAPI] 116 | public static IntPtr StdIn => _inHandle; 117 | 118 | /// 119 | /// Gets the handle to the console standard output. 120 | /// 121 | [PublicAPI] 122 | public static IntPtr StdOut => _outHandle; 123 | 124 | /// 125 | /// Enables virtual terminal features. 126 | /// 127 | /// 128 | /// Enable emulating the cursor positioning and scrolling behavior of other terminal emulators in relation to 129 | /// characters written to the final column in any row. Requires Windows 10 Anniversary Update. 130 | /// 131 | /// 132 | /// true on success. 133 | /// 134 | [PublicAPI] 135 | public static bool Enable(bool disableNewLineAutoReturn = true) 136 | { 137 | if (IsEnabled) 138 | return true; 139 | 140 | bool EnableInput() 141 | { 142 | if (!GetStdIn(out _inHandle)) 143 | return false; 144 | 145 | if (!GetConsoleMode(StdIn, out _inLast)) 146 | return false; 147 | 148 | var mode = _inLast | ConsoleModeInput.EnableVirtualTerminalInput; 149 | 150 | return SetConsoleMode(StdIn, (uint) mode); 151 | } 152 | 153 | bool EnableOutput() 154 | { 155 | if (!GetStdOut(out _outHandle)) 156 | return false; 157 | 158 | if (!GetConsoleMode(StdOut, out _outLast)) 159 | return false; 160 | 161 | var mode = _outLast | ConsoleModeOutput.EnableVirtualTerminalProcessing; 162 | 163 | if (disableNewLineAutoReturn) 164 | mode |= ConsoleModeOutput.DisableNewlineAutoReturn; 165 | 166 | if (SetConsoleMode(StdOut, (uint) mode)) 167 | return true; 168 | 169 | mode = _outLast | ConsoleModeOutput.EnableVirtualTerminalProcessing; 170 | 171 | return SetConsoleMode(StdOut, (uint) mode); 172 | } 173 | 174 | IsEnabled = EnableInput() && EnableOutput(); 175 | 176 | return IsEnabled; 177 | } 178 | 179 | /// 180 | /// Disables virtual terminal features. 181 | /// 182 | /// 183 | /// true on success. 184 | /// 185 | [PublicAPI] 186 | public static bool Disable() 187 | { 188 | if (!IsEnabled) 189 | return false; 190 | 191 | bool DisableInput() 192 | { 193 | return GetStdIn(out var handle) && SetConsoleMode(handle, (uint) _inLast); 194 | } 195 | 196 | bool DisableOutput() 197 | { 198 | return GetStdOut(out var handle) && SetConsoleMode(handle, (uint) _outLast); 199 | } 200 | 201 | IsEnabled = !(DisableInput() && DisableOutput()); 202 | 203 | _inHandle = IntPtr.Zero; 204 | _outHandle = IntPtr.Zero; 205 | _cursorKeysMode = VTCursorKeysMode.Normal; 206 | _keypadMode = VTKeypadMode.Numeric; 207 | 208 | return !IsEnabled; 209 | } 210 | 211 | /// 212 | /// Gets the virtual terminal sequence for a background color. 213 | /// 214 | /// 215 | /// 216 | /// 217 | /// 218 | [PublicAPI] 219 | public static string GetColorBackgroundString(int r, int g, int b) 220 | { 221 | return string.Concat(ESC, "[48;2;", BytesMap[r], ";", BytesMap[g], ";", BytesMap[b], "m"); 222 | } 223 | 224 | /// 225 | /// Gets the virtual terminal sequence for a foreground color. 226 | /// 227 | /// 228 | /// 229 | /// 230 | /// 231 | [PublicAPI] 232 | public static string GetColorForegroundString(int r, int g, int b) 233 | { 234 | return string.Concat(ESC, "[38;2;", BytesMap[r], ";", BytesMap[g], ";", BytesMap[b], "m"); 235 | } 236 | 237 | /// 238 | /// Sets the background color for subsequent write calls. 239 | /// 240 | /// 241 | /// Character background color. 242 | /// 243 | [PublicAPI] 244 | public static void SetColorBackground(Color color) 245 | { 246 | Console.Write(GetColorBackgroundString(color.R, color.G, color.B)); 247 | } 248 | 249 | /// 250 | /// Sets the foreground color for subsequent write calls. 251 | /// 252 | /// 253 | /// Character foreground color, i.e. text color. 254 | /// 255 | [PublicAPI] 256 | public static void SetColorForeground(Color color) 257 | { 258 | Console.Write(GetColorForegroundString(color.R, color.G, color.B)); 259 | } 260 | 261 | /// 262 | /// Sets the formatting options for subsequent write calls. 263 | /// 264 | /// 265 | /// An array of formatting options to apply, 16 at most. Competing options will result in the last-most option taking 266 | /// precedence. 267 | /// 268 | [PublicAPI] 269 | public static void SetFormat(params VTFormat[] formats) 270 | { 271 | if (formats == null || !formats.Any()) 272 | return; 273 | 274 | Console.Write($"{ESC}[{string.Join(";", formats.Take(16).Select(s => (int) s))}m"); 275 | } 276 | 277 | /// 278 | /// Fast writing using WriteConsole. 279 | /// 280 | /// 281 | /// 282 | /// Number of characters written. 283 | /// 284 | [PublicAPI] 285 | public static int WriteFast(byte[] buffer) 286 | { 287 | WriteConsole(StdOut, buffer, buffer.Length, out var written, IntPtr.Zero); 288 | return written; 289 | } 290 | 291 | /// 292 | /// Writes the current line terminator to the standard output. 293 | /// 294 | [PublicAPI] 295 | public static void WriteLine() 296 | { 297 | Console.WriteLine(); 298 | } 299 | 300 | /// 301 | /// Write the specified string value, followed by the current line terminator to the standard output. 302 | /// 303 | /// 304 | /// The value to write. 305 | /// 306 | [PublicAPI] 307 | public static void WriteLine(string value) 308 | { 309 | Console.WriteLine(value); 310 | } 311 | 312 | /// 313 | /// Write the specified string value, followed by the current line terminator to the standard output. 314 | /// 315 | /// 316 | /// The value to write. 317 | /// 318 | /// 319 | /// The color for the text. 320 | /// 321 | [PublicAPI] 322 | public static void WriteLine(string value, Color foreground) 323 | { 324 | SetColorForeground(foreground); 325 | WriteLine(value); 326 | } 327 | 328 | /// 329 | /// Write the specified string value, followed by the current line terminator to the standard output. 330 | /// 331 | /// 332 | /// The value to write. 333 | /// 334 | /// 335 | /// The color for the text. 336 | /// 337 | /// 338 | /// The color for the background. 339 | /// 340 | [PublicAPI] 341 | public static void WriteLine(string value, Color foreground, Color background) 342 | { 343 | SetColorForeground(foreground); 344 | SetColorBackground(background); 345 | WriteLine(value); 346 | } 347 | 348 | /// 349 | /// Write the specified string value to the standard output. 350 | /// 351 | /// 352 | /// The value to write. 353 | /// 354 | [PublicAPI] 355 | public static void Write(string value) 356 | { 357 | Console.Write(value); 358 | } 359 | 360 | /// 361 | /// Write the specified string value to the standard output. 362 | /// 363 | /// 364 | /// The value to write. 365 | /// 366 | /// 367 | /// The color for the text. 368 | /// 369 | [PublicAPI] 370 | public static void Write(string value, Color foreground) 371 | { 372 | SetColorForeground(foreground); 373 | Console.Write(value); 374 | } 375 | 376 | /// 377 | /// Write the specified string value to the standard output. 378 | /// 379 | /// 380 | /// The value to write. 381 | /// 382 | /// 383 | /// The color for the text. 384 | /// 385 | /// 386 | /// The color for the background. 387 | /// 388 | [PublicAPI] 389 | public static void Write(string value, Color foreground, Color background) 390 | { 391 | SetColorForeground(foreground); 392 | SetColorBackground(background); 393 | Console.Write(value); 394 | } 395 | 396 | /// 397 | /// Write the concatenation of specified objects to the standard output. 398 | /// 399 | /// 400 | /// An object array that contains the elements to concatenate. 401 | /// 402 | [PublicAPI] 403 | public static void WriteConcat(params object[] objects) 404 | { 405 | Console.Write(string.Concat(objects)); 406 | } 407 | 408 | #endregion 409 | } 410 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTConsoleCursor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace TrueColorConsole 5 | { 6 | public static partial class VTConsole 7 | { 8 | /// 9 | /// Cursor moves to Nth position horizontally in the current line. 10 | /// 11 | /// 12 | /// Column to move to, one-based. 13 | /// 14 | [PublicAPI] 15 | public static void CursorAbsoluteHorizontal(int column) 16 | { 17 | if (column < 1 || column > short.MaxValue) 18 | throw new ArgumentOutOfRangeException(nameof(column)); 19 | 20 | WriteConcat(ESC, "[", column, "G"); 21 | } 22 | 23 | /// 24 | /// Cursor moves to the Nth position vertically in the current column. 25 | /// 26 | /// 27 | /// Row to move to, one-based. 28 | /// 29 | [PublicAPI] 30 | public static void CursorAbsoluteVertical(int row) 31 | { 32 | if (row < 1 || row > short.MaxValue) 33 | throw new ArgumentOutOfRangeException(nameof(row)); 34 | 35 | WriteConcat(ESC, "[", row, "d"); 36 | } 37 | 38 | /// 39 | /// Performs a restore cursor option like . 40 | /// 41 | [PublicAPI] 42 | public static void CursorAnsiRestore() 43 | { 44 | WriteConcat(ESC, "[u"); 45 | } 46 | 47 | /// 48 | /// Performs a save cursor operation like . 49 | /// 50 | [PublicAPI] 51 | public static void CursorAnsiSave() 52 | { 53 | WriteConcat(ESC, "[s"); 54 | } 55 | 56 | /// 57 | /// Cursor down to beginning of Nth line in the viewport. 58 | /// 59 | /// 60 | /// Line to move to, one-based. 61 | /// 62 | [PublicAPI] 63 | public static void CursorLineDown(int line = 1) 64 | { 65 | if (line < 1 || line > short.MaxValue) 66 | throw new ArgumentOutOfRangeException(nameof(line)); 67 | 68 | WriteConcat(ESC, "[", line, "E"); 69 | } 70 | 71 | /// 72 | /// Cursor up to beginning of Nth line in the viewport. 73 | /// 74 | /// 75 | /// Line to move to, one-based. 76 | /// 77 | [PublicAPI] 78 | public static void CursorLineUp(int line = 1) 79 | { 80 | if (line < 1 || line > short.MaxValue) 81 | throw new ArgumentOutOfRangeException(nameof(line)); 82 | 83 | WriteConcat(ESC, "[", line, "F"); 84 | } 85 | 86 | /// 87 | /// Cursor up by N rows. 88 | /// 89 | /// 90 | /// Number of rows to move by. 91 | /// 92 | [PublicAPI] 93 | public static void CursorMoveUp(int rows = 1) 94 | { 95 | if (rows < 1 || rows > short.MaxValue) 96 | throw new ArgumentOutOfRangeException(nameof(rows)); 97 | 98 | WriteConcat(ESC, "[", rows, "A"); 99 | } 100 | 101 | /// 102 | /// Cursor down by N rows. 103 | /// 104 | /// 105 | /// Number of rows to move by. 106 | /// 107 | [PublicAPI] 108 | public static void CursorMoveDown(int rows = 1) 109 | { 110 | if (rows < 1 || rows > short.MaxValue) 111 | throw new ArgumentOutOfRangeException(nameof(rows)); 112 | 113 | WriteConcat(ESC, "[", rows, "B"); 114 | } 115 | 116 | /// 117 | /// Cursor right by N columns. 118 | /// 119 | /// 120 | /// Number of columns to move by. 121 | /// 122 | [PublicAPI] 123 | public static void CursorMoveRight(int columns = 1) 124 | { 125 | if (columns < 1 || columns > short.MaxValue) 126 | throw new ArgumentOutOfRangeException(nameof(columns)); 127 | 128 | WriteConcat(ESC, "[", columns, "C"); 129 | } 130 | 131 | /// 132 | /// Cursor left by N columns. 133 | /// 134 | /// 135 | /// Number of columns to move by. 136 | /// 137 | [PublicAPI] 138 | public static void CursorMoveLeft(int columns = 1) 139 | { 140 | if (columns < 1 || columns > short.MaxValue) 141 | throw new ArgumentOutOfRangeException(nameof(columns)); 142 | 143 | WriteConcat(ESC, "[", columns, "D"); 144 | } 145 | 146 | /// 147 | /// Cursor move to coordinates within the viewport. 148 | /// 149 | /// 150 | /// Column to move to, one-based. 151 | /// 152 | /// 153 | /// Row to move to, one-based. 154 | /// 155 | [PublicAPI] 156 | public static void CursorPosition(int column, int row) 157 | { 158 | if (column < 1 || column > short.MaxValue) 159 | throw new ArgumentOutOfRangeException(nameof(column)); 160 | 161 | if (row < 1 || row > short.MaxValue) 162 | throw new ArgumentOutOfRangeException(nameof(row)); 163 | 164 | WriteConcat(ESC, "[", column, ";", row, "H"); 165 | } 166 | 167 | /// 168 | /// Restore cursor position in memory (see Remarks). 169 | /// 170 | /// 171 | /// There will be no value saved in memory until the first use of the save command. The only way to access the saved 172 | /// value is with the restore command. 173 | /// 174 | [PublicAPI] 175 | public static void CursorPositionRestore() 176 | { 177 | WriteConcat(ESC, 8); 178 | } 179 | 180 | /// 181 | /// Save cursor position in memory (see Remarks). 182 | /// 183 | /// 184 | /// There will be no value saved in memory until the first use of the save command. The only way to access the saved 185 | /// value is with the restore command. 186 | /// 187 | [PublicAPI] 188 | public static void CursorPositionSave() 189 | { 190 | WriteConcat(ESC, 7); 191 | } 192 | 193 | /// 194 | /// Reverse Index – Performs the reverse operation of \n, moves cursor up one line, maintains horizontal position, 195 | /// scrolls buffer if necessary (see Remarks). 196 | /// 197 | /// 198 | /// If there are scroll margins set, RI inside the margins will scroll only the contents of the margins, and leave the 199 | /// viewport unchanged. 200 | /// 201 | [PublicAPI] 202 | public static void CursorReverseIndex() 203 | { 204 | WriteConcat(ESC, "M"); 205 | } 206 | 207 | /// 208 | /// Sets cursor blinking. 209 | /// 210 | /// 211 | /// Enable blinking. 212 | /// 213 | [PublicAPI] 214 | public static void CursorSetBlinking(bool enabled) 215 | { 216 | WriteConcat(ESC, "[?12", enabled ? "h" : "l"); 217 | } 218 | 219 | /// 220 | /// Sets cursor visibility. 221 | /// 222 | /// 223 | /// Enable visibility. 224 | /// 225 | [PublicAPI] 226 | public static void CursorSetVisibility(bool enabled) 227 | { 228 | WriteConcat(ESC, "[?25", enabled ? "h" : "l"); 229 | } 230 | } 231 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTConsoleInputSequences.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace TrueColorConsole 5 | { 6 | public static partial class VTConsole 7 | { 8 | /// 9 | /// Emits a key. 10 | /// 11 | /// 12 | /// Cursor key to emit. 13 | /// 14 | [PublicAPI] 15 | public static void Emit(VTCursorKey cursorKey) 16 | { 17 | string s; 18 | 19 | switch (CursorKeysMode) 20 | { 21 | case VTCursorKeysMode.Application: 22 | s = "O"; 23 | break; 24 | case VTCursorKeysMode.Normal: 25 | s = "["; 26 | break; 27 | default: 28 | throw new ArgumentOutOfRangeException(); 29 | } 30 | 31 | switch (cursorKey) 32 | { 33 | case VTCursorKey.UpArrow: 34 | WriteConcat(ESC, s, "A"); 35 | break; 36 | case VTCursorKey.DownArrow: 37 | WriteConcat(ESC, s, "B"); 38 | break; 39 | case VTCursorKey.RightArrow: 40 | WriteConcat(ESC, s, "C"); 41 | break; 42 | case VTCursorKey.LeftArrow: 43 | WriteConcat(ESC, s, "D"); 44 | break; 45 | case VTCursorKey.Home: 46 | WriteConcat(ESC, s, "H"); 47 | break; 48 | case VTCursorKey.End: 49 | WriteConcat(ESC, s, "F"); 50 | break; 51 | case VTCursorKey.CtrlUpArrow: 52 | WriteConcat(ESC, "[1;5A"); 53 | break; 54 | case VTCursorKey.CtrlDownArrow: 55 | WriteConcat(ESC, "[1;5B"); 56 | break; 57 | case VTCursorKey.CtrlRightArrow: 58 | WriteConcat(ESC, "[1;5C"); 59 | break; 60 | case VTCursorKey.CtrlLeftArrow: 61 | WriteConcat(ESC, "[1;5D"); 62 | break; 63 | default: 64 | throw new ArgumentOutOfRangeException(nameof(cursorKey), cursorKey, null); 65 | } 66 | } 67 | 68 | /// 69 | /// Emits a key. 70 | /// 71 | /// 72 | /// Key to emit. 73 | /// 74 | [PublicAPI] 75 | public static void Emit(VTKey key) 76 | { 77 | switch (key) 78 | { 79 | case VTKey.Backspace: 80 | WriteConcat(DEL); 81 | break; 82 | case VTKey.Pause: 83 | WriteConcat(SUB); 84 | break; 85 | case VTKey.Escape: 86 | WriteConcat(ESC); 87 | break; 88 | case VTKey.Insert: 89 | WriteConcat(ESC, "[2~"); 90 | break; 91 | case VTKey.Delete: 92 | WriteConcat(ESC, "[3~"); 93 | break; 94 | case VTKey.PageUp: 95 | WriteConcat(ESC, "[5~"); 96 | break; 97 | case VTKey.PageDown: 98 | WriteConcat(ESC, "[6~"); 99 | break; 100 | case VTKey.F1: 101 | WriteConcat(ESC, "OP"); 102 | break; 103 | case VTKey.F2: 104 | WriteConcat(ESC, "OQ"); 105 | break; 106 | case VTKey.F3: 107 | WriteConcat(ESC, "OR"); 108 | break; 109 | case VTKey.F4: 110 | WriteConcat(ESC, "OS"); 111 | break; 112 | case VTKey.F5: 113 | WriteConcat(ESC, "[15~"); 114 | break; 115 | case VTKey.F6: 116 | WriteConcat(ESC, "[17~"); 117 | break; 118 | case VTKey.F7: 119 | WriteConcat(ESC, "[18~"); 120 | break; 121 | case VTKey.F8: 122 | WriteConcat(ESC, "[19~"); 123 | break; 124 | case VTKey.F9: 125 | WriteConcat(ESC, "[20~"); 126 | break; 127 | case VTKey.F10: 128 | WriteConcat(ESC, "[21~"); 129 | break; 130 | case VTKey.F11: 131 | WriteConcat(ESC, "[23~"); 132 | break; 133 | case VTKey.F12: 134 | WriteConcat(ESC, "[24~"); 135 | break; 136 | default: 137 | throw new ArgumentOutOfRangeException(nameof(key), key, null); 138 | } 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTConsoleMisc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace TrueColorConsole 5 | { 6 | public static partial class VTConsole 7 | { 8 | /// 9 | /// Sets the active character mode. 10 | /// 11 | /// 12 | /// Character set to use. 13 | /// 14 | [PublicAPI] 15 | public static void SetCharacterMode(VTCharSet charSet) 16 | { 17 | switch (charSet) 18 | { 19 | case VTCharSet.Ascii: 20 | WriteConcat(ESC, "(B"); 21 | break; 22 | case VTCharSet.DecLineDrawing: 23 | WriteConcat(ESC, "(0"); 24 | break; 25 | default: 26 | throw new ArgumentOutOfRangeException(nameof(charSet), charSet, null); 27 | } 28 | } 29 | 30 | /// 31 | /// Sets the VT scrolling margins of the viewport. 32 | /// 33 | /// 34 | /// Top line of the scroll region, one-based, inclusive. 35 | /// 36 | /// 37 | /// Bottom line of the scroll region, one-based, inclusive. 38 | /// 39 | [PublicAPI] 40 | public static void SetScrollingRegion(int top, int bottom) 41 | { 42 | if (top < 1 || top > short.MaxValue) 43 | throw new ArgumentOutOfRangeException(nameof(top)); 44 | 45 | if (bottom < 1 || bottom > short.MaxValue) 46 | throw new ArgumentOutOfRangeException(nameof(bottom)); 47 | 48 | WriteConcat(ESC, "[", top, ";", bottom, "r"); 49 | } 50 | 51 | /// 52 | /// Sets the console window’s title. 53 | /// 54 | /// 55 | /// Text for the console window title, 255 characters at most. 56 | /// 57 | [PublicAPI] 58 | public static void SetWindowTitle([CanBeNull] string text) 59 | { 60 | if (text == null) 61 | text = string.Empty; 62 | 63 | if (text.Length > 255) 64 | throw new ArgumentOutOfRangeException(nameof(text)); 65 | 66 | WriteConcat(ESC.Length, "]2;", text, BEL); 67 | } 68 | 69 | /// 70 | /// Sets the console window’s title. 71 | /// 72 | /// 73 | /// Text for the console window title, 255 characters at most. 74 | /// 75 | [PublicAPI] 76 | public static void SetWindowTitleAndIcon([CanBeNull] string text) 77 | { 78 | if (text == null) 79 | text = string.Empty; 80 | 81 | if (text.Length > 255) 82 | throw new ArgumentOutOfRangeException(nameof(text)); 83 | 84 | WriteConcat(ESC.Length, "]0;", text, BEL); 85 | } 86 | 87 | /// 88 | /// Switches to a new alternate screen buffer. 89 | /// 90 | [PublicAPI] 91 | public static void SwitchScreenBufferAlternate() 92 | { 93 | WriteConcat(ESC, "[?1049h"); 94 | } 95 | 96 | /// 97 | /// Switches to the main buffer. 98 | /// 99 | [PublicAPI] 100 | public static void SwitchScreenBufferMain() 101 | { 102 | WriteConcat(ESC, "[?1049l"); 103 | } 104 | 105 | /// 106 | /// Sets the console width to 80 columns wide. 107 | /// 108 | [PublicAPI] 109 | public static void SetConsoleWidth80() 110 | { 111 | WriteConcat(ESC, "[?3l"); 112 | } 113 | 114 | /// 115 | /// Sets the console width to 132 columns wide. 116 | /// 117 | [PublicAPI] 118 | public static void SetConsoleWidth132() 119 | { 120 | WriteConcat(ESC, "[?3h"); 121 | } 122 | 123 | /// 124 | /// Reset certain terminal settings to their defaults. 125 | /// 126 | [PublicAPI] 127 | public static void SoftReset() 128 | { 129 | WriteConcat(ESC, "[!p"); 130 | } 131 | } 132 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTConsoleModeChanges.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace TrueColorConsole 5 | { 6 | public static partial class VTConsole 7 | { 8 | private static VTCursorKeysMode _cursorKeysMode = VTCursorKeysMode.Normal; 9 | private static VTKeypadMode _keypadMode = VTKeypadMode.Numeric; 10 | 11 | /// 12 | /// Gets or sets the mode for cursor keys. 13 | /// 14 | [PublicAPI] 15 | public static VTCursorKeysMode CursorKeysMode 16 | { 17 | get => _cursorKeysMode; 18 | set 19 | { 20 | switch (value) 21 | { 22 | case VTCursorKeysMode.Normal: 23 | WriteConcat(ESC, "[?1l"); 24 | break; 25 | case VTCursorKeysMode.Application: 26 | WriteConcat(ESC, "[?1h"); 27 | break; 28 | default: 29 | throw new ArgumentOutOfRangeException(nameof(value), value, null); 30 | } 31 | _cursorKeysMode = value; 32 | } 33 | } 34 | 35 | /// 36 | /// Gets or sets the mode for keypad keys. 37 | /// 38 | [PublicAPI] 39 | public static VTKeypadMode KeypadMode 40 | { 41 | get => _keypadMode; 42 | set 43 | { 44 | switch (value) 45 | { 46 | case VTKeypadMode.Numeric: 47 | WriteConcat(ESC, ">"); 48 | break; 49 | case VTKeypadMode.Application: 50 | WriteConcat(ESC, "="); 51 | break; 52 | default: 53 | throw new ArgumentOutOfRangeException(nameof(value), value, null); 54 | } 55 | _keypadMode = value; 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTConsoleQueryState.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace TrueColorConsole 4 | { 5 | public static partial class VTConsole 6 | { 7 | /// 8 | /// Emit the cursor position as: ESC [ <r> ; <c> R where <r> = cursor row and <c> = cursor 9 | /// column. 10 | /// 11 | [PublicAPI] 12 | public static void QueryCursorPosition() 13 | { 14 | WriteConcat(ESC, "[6n"); 15 | } 16 | 17 | /// 18 | /// Report the terminal identity. Will emit “\x1b[?1;0c”, indicating "VT101 with No Options". 19 | /// 20 | [PublicAPI] 21 | public static void QueryDeviceAttributes() 22 | { 23 | WriteConcat(ESC, "[0c"); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTConsoleTabs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace TrueColorConsole 5 | { 6 | public static partial class VTConsole 7 | { 8 | /// 9 | /// Sets a tab stop in the current column the cursor is in. 10 | /// 11 | [PublicAPI] 12 | public static void TabHorizontalSet() 13 | { 14 | WriteConcat(ESC, "H"); 15 | } 16 | 17 | /// 18 | /// Advance the cursor to the next column (in the same row) with a tab stop. If there are no more tab stops, move to 19 | /// the last column in the row. If the cursor is in the last column, move to the first column of the next row. 20 | /// 21 | /// 22 | /// Number of columns to move by, one-based. 23 | /// 24 | [PublicAPI] 25 | public static void TabCursorForward(int columns) 26 | { 27 | if (columns < 1 || columns > short.MaxValue) 28 | throw new ArgumentOutOfRangeException(nameof(columns)); 29 | 30 | WriteConcat(ESC, "[", columns, "l"); 31 | } 32 | 33 | /// 34 | /// Move the cursor to the previous column (in the same row) with a tab stop. If there are no more tab stops, moves the 35 | /// cursor to the first column. If the cursor is in the first column, doesn’t move the cursor. 36 | /// 37 | /// 38 | /// Number of columns to move by, one-based. 39 | /// 40 | [PublicAPI] 41 | public static void TabCursorBackward(int columns) 42 | { 43 | if (columns < 1 || columns > short.MaxValue) 44 | throw new ArgumentOutOfRangeException(nameof(columns)); 45 | 46 | WriteConcat(ESC, "[", columns, "Z"); 47 | } 48 | 49 | /// 50 | /// Clears the tab stop in the current column, if there is one. Otherwise does nothing. 51 | /// 52 | [PublicAPI] 53 | public static void TabClear() 54 | { 55 | WriteConcat(ESC, "[0g"); 56 | } 57 | 58 | /// 59 | /// Clears all currently set tab stops. 60 | /// 61 | [PublicAPI] 62 | public static void TabClearAll() 63 | { 64 | WriteConcat(ESC, "[3g"); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTConsoleTextModification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace TrueColorConsole 5 | { 6 | public static partial class VTConsole 7 | { 8 | /// 9 | /// Insert N spaces at the current cursor position, shifting all existing text to the right. Text exiting the screen to 10 | /// the right is removed. 11 | /// 12 | /// 13 | /// Number of characters to insert. 14 | /// 15 | [PublicAPI] 16 | public static void CharacterInsert(int count = 1) 17 | { 18 | if (count < 1) 19 | throw new ArgumentOutOfRangeException(nameof(count)); 20 | 21 | WriteConcat(ESC, "[", count, "@"); 22 | } 23 | 24 | /// 25 | /// Delete N characters at the current cursor position, shifting in space characters from the right edge of the screen. 26 | /// 27 | /// 28 | /// Number of characters to delete. 29 | /// 30 | [PublicAPI] 31 | public static void CharacterDelete(int count = 1) 32 | { 33 | if (count < 1) 34 | throw new ArgumentOutOfRangeException(nameof(count)); 35 | 36 | WriteConcat(ESC, "[", count, "P"); 37 | } 38 | 39 | /// 40 | /// Erase N characters from the current cursor position by overwriting them with a space character. 41 | /// 42 | /// 43 | /// Number of characters to erase. 44 | /// 45 | [PublicAPI] 46 | public static void CharacterErase(int count = 1) 47 | { 48 | if (count < 1) 49 | throw new ArgumentOutOfRangeException(nameof(count)); 50 | 51 | WriteConcat(ESC, "[", count, "X"); 52 | } 53 | 54 | /// 55 | /// Inserts N lines into the buffer at the cursor position. The line the cursor is on, and lines below it, will be 56 | /// shifted downwards. 57 | /// 58 | /// 59 | /// Number of lines to insert. 60 | /// 61 | [PublicAPI] 62 | public static void LineInsert(int count = 1) 63 | { 64 | if (count < 1) 65 | throw new ArgumentOutOfRangeException(nameof(count)); 66 | 67 | WriteConcat(ESC, "[", count, "L"); 68 | } 69 | 70 | /// 71 | /// Deletes N lines from the buffer, starting with the row the cursor is on. 72 | /// 73 | /// 74 | /// Number of lines to delete. 75 | /// 76 | [PublicAPI] 77 | public static void LineDelete(int count = 1) 78 | { 79 | if (count < 1) 80 | throw new ArgumentOutOfRangeException(nameof(count)); 81 | 82 | WriteConcat(ESC, "[", count, "M"); 83 | } 84 | 85 | /// 86 | /// Replace all text in the current viewport/screen with space characters. 87 | /// 88 | /// 89 | /// Erase mode for the replacement. 90 | /// 91 | [PublicAPI] 92 | public static void EraseInDisplay(VTEraseMode eraseMode = VTEraseMode.FromCursorToEnd) 93 | { 94 | WriteConcat(ESC, "[", (int) eraseMode, "J"); 95 | } 96 | 97 | /// 98 | /// Replace all text on the line with the cursor with space characters. 99 | /// 100 | /// 101 | /// Erase mode for the replacement. 102 | /// 103 | [PublicAPI] 104 | public static void EraseInLine(VTEraseMode eraseMode = VTEraseMode.FromCursorToEnd) 105 | { 106 | WriteConcat(ESC, "[", (int) eraseMode, "K"); 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTConsoleViewport.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace TrueColorConsole 5 | { 6 | public static partial class VTConsole 7 | { 8 | /// 9 | /// Scroll text up by N lines. Also known as pan down, new lines fill in from the bottom of the screen. 10 | /// 11 | /// 12 | /// Number of lines to scroll by. 13 | /// 14 | [PublicAPI] 15 | public static void ScrollUp(int lines = 1) 16 | { 17 | if (lines < 1) 18 | throw new ArgumentOutOfRangeException(nameof(lines)); 19 | 20 | WriteConcat(ESC, "[", lines, "S"); 21 | } 22 | 23 | /// 24 | /// Scroll down by N lines. Also known as pan up, new lines fill in from the top of the screen. 25 | /// 26 | /// 27 | /// Number of lines to scroll by. 28 | /// 29 | [PublicAPI] 30 | public static void ScrollDown(int lines = 1) 31 | { 32 | if (lines < 1) 33 | throw new ArgumentOutOfRangeException(nameof(lines)); 34 | 35 | WriteConcat(ESC, "[", lines, "T"); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTCursorKey.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace TrueColorConsole 4 | { 5 | /// 6 | /// Defines cursor keys. 7 | /// 8 | [PublicAPI] 9 | public enum VTCursorKey 10 | { 11 | /// 12 | /// 'Up arrow' key. 13 | /// 14 | UpArrow, 15 | 16 | /// 17 | /// 'Down arrow' key. 18 | /// 19 | DownArrow, 20 | 21 | /// 22 | /// 'Right arrow' key. 23 | /// 24 | RightArrow, 25 | 26 | /// 27 | /// 'Left arrow' key. 28 | /// 29 | LeftArrow, 30 | 31 | /// 32 | /// 'Home' key. 33 | /// 34 | Home, 35 | 36 | /// 37 | /// 'End' key. 38 | /// 39 | End, 40 | 41 | /// 42 | /// 'Ctrl' + 'Up arrow' keys. 43 | /// 44 | CtrlUpArrow, 45 | 46 | /// 47 | /// 'Ctrl' + 'Down arrow' keys. 48 | /// 49 | CtrlDownArrow, 50 | 51 | /// 52 | /// 'Ctrl' + 'Right arrow' keys. 53 | /// 54 | CtrlRightArrow, 55 | 56 | /// 57 | /// 'Ctrl' + 'Left arrow' keys. 58 | /// 59 | CtrlLeftArrow 60 | } 61 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTCursorKeysMode.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace TrueColorConsole 4 | { 5 | /// 6 | /// Defines the mode for cursor keys. 7 | /// 8 | [PublicAPI] 9 | public enum VTCursorKeysMode 10 | { 11 | /// 12 | /// Cursor keys will emit their Application Mode sequences. 13 | /// 14 | Application, 15 | 16 | /// 17 | /// Cursor keys will emit their Numeric Mode sequences. 18 | /// 19 | Normal 20 | } 21 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTDecLine.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace TrueColorConsole 4 | { 5 | /// 6 | /// Defines DEC line drawing elements. 7 | /// 8 | [PublicAPI] 9 | public enum VTDecLine : byte 10 | { 11 | /// 12 | /// Lower-right crossing. 13 | /// 14 | LowerRightCrossing = (byte) 'j', 15 | 16 | /// 17 | /// Upper-right crossing. 18 | /// 19 | UpperRightCrossing = (byte) 'k', 20 | 21 | /// 22 | /// Upper-left crossing. 23 | /// 24 | UpperLeftCrossing = (byte) 'l', 25 | 26 | /// 27 | /// Lower-left crossing. 28 | /// 29 | LowerLeftCrossing = (byte) 'm', 30 | 31 | /// 32 | /// Crossing lines. 33 | /// 34 | CrossingLines = (byte) 'n', 35 | 36 | /// 37 | /// Horizontal line. 38 | /// 39 | HorizontalLine = (byte) 'q', 40 | 41 | /// 42 | /// Left T. 43 | /// 44 | LeftT = (byte) 't', 45 | 46 | /// 47 | /// Right T. 48 | /// 49 | RightT = (byte) 'u', 50 | 51 | /// 52 | /// Bottom T. 53 | /// 54 | BottomT = (byte) 'v', 55 | 56 | /// 57 | /// Top T. 58 | /// 59 | TopT = (byte) 'w', 60 | 61 | /// 62 | /// Vertical bar. 63 | /// 64 | VerticalBar = (byte) 'x' 65 | } 66 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTEraseMode.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace TrueColorConsole 4 | { 5 | /// 6 | /// Defines the mode for erasure. 7 | /// 8 | [PublicAPI] 9 | public enum VTEraseMode 10 | { 11 | /// 12 | /// Erases from the beginning of the line/display up to and including the current cursor position. 13 | /// 14 | FromBeginningToCursor = 0, 15 | 16 | /// 17 | /// Erases from the current cursor position (inclusive) to the end of the line/display. 18 | /// 19 | FromCursorToEnd = 1, 20 | 21 | /// 22 | /// Erases the entire line/display. 23 | /// 24 | Entirely = 2 25 | } 26 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTFormat.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace TrueColorConsole 4 | { 5 | /// 6 | /// Defines formatting options. 7 | /// 8 | [PublicAPI] 9 | public enum VTFormat 10 | { 11 | /// 12 | /// Returns all attributes to the default state prior to modification. 13 | /// 14 | Default = 0, 15 | 16 | /// 17 | /// Applies brightness/intensity flag to foreground color. 18 | /// 19 | BoldBright = 1, 20 | 21 | /// 22 | /// Adds underline. 23 | /// 24 | Underline = 4, 25 | 26 | /// 27 | /// Removes underline. 28 | /// 29 | NoUnderline = 24, 30 | 31 | /// 32 | /// Swaps foreground and background colors. 33 | /// 34 | Negative = 7, 35 | 36 | /// 37 | /// Returns foreground/background to normal. 38 | /// 39 | Positive = 27, 40 | 41 | /// 42 | /// Applies non-bold/bright black to foreground. 43 | /// 44 | ForegroundBlack = 30, 45 | 46 | /// 47 | /// Applies non-bold/bright red to foreground. 48 | /// 49 | ForegroundRed = 31, 50 | 51 | /// 52 | /// Applies non-bold/bright green to foreground. 53 | /// 54 | ForegroundGreen = 32, 55 | 56 | /// 57 | /// Applies non-bold/bright yellow to foreground. 58 | /// 59 | ForegroundYellow = 33, 60 | 61 | /// 62 | /// Applies non-bold/bright blue to foreground. 63 | /// 64 | ForegroundBlue = 34, 65 | 66 | /// 67 | /// Applies non-bold/bright magenta to foreground. 68 | /// 69 | ForegroundMagenta = 35, 70 | 71 | /// 72 | /// Applies non-bold/bright cyan to foreground. 73 | /// 74 | ForegroundCyan = 36, 75 | 76 | /// 77 | /// Applies non-bold/bright white to foreground. 78 | /// 79 | ForegroundWhite = 37, 80 | 81 | // ForegroundExtended = 38, // NOTE using methods instead 82 | /// 83 | /// Applies only the foreground portion of the defaults (see ). 84 | /// 85 | ForegroundDefault = 39, 86 | 87 | /// 88 | /// Applies non-bold/bright black to background. 89 | /// 90 | BackgroundBlack = 40, 91 | 92 | /// 93 | /// Applies non-bold/bright red to background. 94 | /// 95 | BackgroundRed = 41, 96 | 97 | /// 98 | /// Applies non-bold/bright green to background. 99 | /// 100 | BackgroundGreen = 42, 101 | 102 | /// 103 | /// Applies non-bold/bright yellow to background. 104 | /// 105 | BackgroundYellow = 43, 106 | 107 | /// 108 | /// Applies non-bold/bright blue to background. 109 | /// 110 | BackgroundBlue = 44, 111 | 112 | /// 113 | /// Applies non-bold/bright magenta to background. 114 | /// 115 | BackgroundMagenta = 45, 116 | 117 | /// 118 | /// Applies non-bold/bright cyan to background. 119 | /// 120 | BackgroundCyan = 46, 121 | 122 | /// 123 | /// Applies non-bold/bright white to background. 124 | /// 125 | BackgroundWhite = 47, 126 | 127 | // BackgroundExtended = 48, // NOTE using methods instead 128 | 129 | /// 130 | /// Applies only the background portion of the defaults (see ). 131 | /// 132 | BackgroundDefault = 49, 133 | 134 | /// 135 | /// Applies bold/bright black to foreground. 136 | /// 137 | BrightForegroundBlack = 90, 138 | 139 | /// 140 | /// Applies bold/bright red to foreground. 141 | /// 142 | BrightForegroundRed = 91, 143 | 144 | /// 145 | /// Applies bold/bright green to foreground. 146 | /// 147 | BrightForegroundGreen = 92, 148 | 149 | /// 150 | /// Applies bold/bright yellow to foreground. 151 | /// 152 | BrightForegroundYellow = 93, 153 | 154 | /// 155 | /// Applies bold/bright blue to foreground. 156 | /// 157 | BrightForegroundBlue = 94, 158 | 159 | /// 160 | /// Applies bold/bright magenta to foreground. 161 | /// 162 | BrightForegroundMagenta = 95, 163 | 164 | /// 165 | /// Applies bold/bright cyan to foreground. 166 | /// 167 | BrightForegroundCyan = 96, 168 | 169 | /// 170 | /// Applies bold/bright white to foreground. 171 | /// 172 | BrightForegroundWhite = 97, 173 | 174 | /// 175 | /// Applies bold/bright black to background. 176 | /// 177 | BrightBackgroundBlack = 100, 178 | 179 | /// 180 | /// Applies bold/bright red to background. 181 | /// 182 | BrightBackgroundRed = 101, 183 | 184 | /// 185 | /// Applies bold/bright green to background. 186 | /// 187 | BrightBackgroundGreen = 102, 188 | 189 | /// 190 | /// Applies bold/bright yellow to background. 191 | /// 192 | BrightBackgroundYellow = 103, 193 | 194 | /// 195 | /// Applies bold/bright blue to background. 196 | /// 197 | BrightBackgroundBlue = 104, 198 | 199 | /// 200 | /// Applies bold/bright magenta to background. 201 | /// 202 | BrightBackgroundMagenta = 105, 203 | 204 | /// 205 | /// Applies bold/bright cyan to background. 206 | /// 207 | BrightBackgroundCyan = 106, 208 | 209 | /// 210 | /// Applies bold/bright white to background. 211 | /// 212 | BrightBackgroundWhite = 107 213 | } 214 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTKey.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace TrueColorConsole 4 | { 5 | /// 6 | /// Defines keypad keys. 7 | /// 8 | [PublicAPI] 9 | public enum VTKey 10 | { 11 | /// 12 | /// 'Backspace' key. 13 | /// 14 | Backspace, 15 | 16 | /// 17 | /// 'Pause' key. 18 | /// 19 | Pause, 20 | 21 | /// 22 | /// 'Escape' key. 23 | /// 24 | Escape, 25 | 26 | /// 27 | /// 'Insert' key. 28 | /// 29 | Insert, 30 | 31 | /// 32 | /// 'Delete' key. 33 | /// 34 | Delete, 35 | 36 | /// 37 | /// 'PageUp' key. 38 | /// 39 | PageUp, 40 | 41 | /// 42 | /// 'PageDown' key. 43 | /// 44 | PageDown, 45 | 46 | /// 47 | /// 'F1' key. 48 | /// 49 | F1, 50 | 51 | /// 52 | /// 'F2' key. 53 | /// 54 | F2, 55 | 56 | /// 57 | /// 'F3' key. 58 | /// 59 | F3, 60 | 61 | /// 62 | /// 'F4' key. 63 | /// 64 | F4, 65 | 66 | /// 67 | /// 'F5' key. 68 | /// 69 | F5, 70 | 71 | /// 72 | /// 'F6' key. 73 | /// 74 | F6, 75 | 76 | /// 77 | /// 'F7' key. 78 | /// 79 | F7, 80 | 81 | /// 82 | /// 'F8' key. 83 | /// 84 | F8, 85 | 86 | /// 87 | /// 'F9' key. 88 | /// 89 | F9, 90 | 91 | /// 92 | /// 'F10' key. 93 | /// 94 | F10, 95 | 96 | /// 97 | /// 'F11' key. 98 | /// 99 | F11, 100 | 101 | /// 102 | /// 'F12' key. 103 | /// 104 | F12 105 | } 106 | } -------------------------------------------------------------------------------- /TrueColorConsole/VTKeypadMode.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | 3 | namespace TrueColorConsole 4 | { 5 | /// 6 | /// Defines the modes for keypad keys. 7 | /// 8 | [PublicAPI] 9 | public enum VTKeypadMode 10 | { 11 | /// 12 | /// Keypad keys will emit their Application Mode sequences. 13 | /// 14 | Application, 15 | 16 | /// 17 | /// Keypad keys will emit their Numeric Mode sequences. 18 | /// 19 | Numeric 20 | } 21 | } -------------------------------------------------------------------------------- /TrueColorConsoleApp/Plasma.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TrueColorConsoleApp 4 | { 5 | public class Plasma 6 | { 7 | public readonly int[] ColB = new int[256]; 8 | public readonly int[] ColG = new int[256]; 9 | public readonly int[] ColR = new int[256]; 10 | 11 | private readonly double[] Rand1 = new double[3]; 12 | private readonly double[] Rand2 = new double[6]; 13 | public readonly byte[] Screen; 14 | 15 | public readonly int SizeX; 16 | public readonly int SizeY; 17 | private readonly byte[] Table; 18 | private readonly int TableX; 19 | private readonly int TableY; 20 | 21 | public Plasma(int sizeX, int sizeY) 22 | { 23 | SizeX = sizeX; 24 | SizeY = sizeY; 25 | 26 | TableX = SizeX * 2; 27 | TableY = SizeY * 2; 28 | Table = new byte[TableX * TableY]; 29 | Screen = new byte[SizeX * SizeY]; 30 | var random = new Random(); 31 | 32 | for (var i = 0; i < 3; i++) 33 | Rand1[i] = (double) random.Next(1, 1000) / 30000 * Math.PI; 34 | 35 | for (var i = 0; i < 6; i++) 36 | Rand2[i] = (double) random.Next(1, 1000) / 5000; 37 | 38 | for (var y = 0; y < TableY; y++) 39 | for (var x = 0; x < TableX; x++) 40 | { 41 | var tmp = ((x - TableX / 2) * (x - TableX / 2) 42 | + 43 | (y - TableX / 2) * (y - TableX / 2)) 44 | * 45 | (Math.PI / (TableX * TableX + TableY * TableY)); 46 | 47 | Table[x + y * TableX] = (byte) ((1.0 + Math.Sin(12.0 * Math.Sqrt(tmp))) * 256 / 6); 48 | } 49 | } 50 | 51 | public void PlasmaFrame(int frame) 52 | { 53 | for (var i = 0; i < 256; i++) 54 | { 55 | var z = (double) i / 256 * 6 * Math.PI; 56 | ColR[i] = (int) ((1.0 + Math.Cos(z + Rand1[0] * frame)) / 2 * 4095); 57 | ColG[i] = (int) ((1.0 + Math.Sin(z + Rand1[1] * frame)) / 2 * 4095); 58 | ColB[i] = (int) ((1.0 + Math.Cos(z + Rand1[2] * frame)) / 2 * 4095); 59 | } 60 | 61 | PlasmaFrame(Screen, 62 | (1.0 + Math.Sin(frame * Rand2[0])) / 2, 63 | (1.0 + Math.Sin(frame * Rand2[1])) / 2, 64 | (1.0 + Math.Sin(frame * Rand2[2])) / 2, 65 | (1.0 + Math.Sin(frame * Rand2[3])) / 2, 66 | (1.0 + Math.Sin(frame * Rand2[4])) / 2, 67 | (1.0 + Math.Sin(frame * Rand2[5])) / 2); 68 | } 69 | 70 | private void PlasmaFrame( 71 | byte[] pixels, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3) 72 | { 73 | var tablex = TableX; 74 | var tabley = TableY; 75 | var X1 = (int) (dx1 * (tablex / 2)); 76 | var Y1 = (int) (dy1 * (tabley / 2)); 77 | var X2 = (int) (dx2 * (tablex / 2)); 78 | var Y2 = (int) (dy2 * (tabley / 2)); 79 | var X3 = (int) (dx3 * (tablex / 2)); 80 | var Y3 = (int) (dy3 * (tabley / 2)); 81 | var t1 = X1 + Y1 * tablex; 82 | var t2 = X2 + Y2 * tablex; 83 | var t3 = X3 + Y3 * tablex; 84 | 85 | for (var y = 0; y < SizeY; y++) 86 | { 87 | var tmp = y * SizeY; 88 | int ty = y * tablex, tmax = ty + SizeX; 89 | for (var x = 0; ty < tmax; ty++, tmp++) 90 | { 91 | var b = (byte) (Table[t1 + ty] + Table[t2 + ty] + Table[t3 + ty]); 92 | pixels[tmp] = b; 93 | } 94 | } 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /TrueColorConsoleApp/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Text; 4 | using System.Threading; 5 | using TrueColorConsole; 6 | 7 | namespace TrueColorConsoleApp 8 | { 9 | internal static class Program 10 | { 11 | private static void Main(string[] args) 12 | { 13 | if (!VTConsole.IsSupported) 14 | throw new NotSupportedException(); 15 | 16 | VTConsole.Enable(); 17 | 18 | Example3(); 19 | 20 | Console.ReadKey(); 21 | } 22 | 23 | private static int Example1() 24 | { 25 | var width = 80; 26 | var height = 25; 27 | Console.SetWindowSize(width, height); 28 | Console.SetBufferSize(width, height); 29 | Console.SetWindowSize(width, height); 30 | 31 | var cx = Console.WindowWidth; 32 | var cy = Console.WindowHeight; 33 | for (var y = 0; y < cy; y++) 34 | for (var x = 0; x < cx; x++) 35 | { 36 | var r = (int) ((float) x / cx * 255); 37 | var g = (int) ((float) y / cy * 255); 38 | var b = (int) (1.0f * 255); 39 | var value = $"{(y * cx + x) % 10}"; 40 | VTConsole.Write(value, Color.Black, Color.FromArgb(r, g, b)); 41 | } 42 | return cy; 43 | } 44 | 45 | private static void Example2() 46 | { 47 | for (var i = 0; i < Console.WindowHeight / 4; i++) 48 | { 49 | Sleep(50); 50 | VTConsole.ScrollUp(); 51 | } 52 | 53 | VTConsole.WriteLine("Disabling cursor blinking", Color.White, Color.Red); 54 | VTConsole.CursorSetBlinking(false); 55 | Sleep(); 56 | 57 | VTConsole.WriteLine("Enabling cursor blinking", Color.White, Color.Green); 58 | VTConsole.CursorSetBlinking(true); 59 | Sleep(); 60 | 61 | VTConsole.SetColorBackground(Color.White); 62 | VTConsole.WriteLine("Hiding cursor", Color.DeepPink); 63 | VTConsole.CursorSetVisibility(false); 64 | Sleep(); 65 | 66 | VTConsole.WriteLine("Showing cursor", Color.DeepSkyBlue); 67 | VTConsole.CursorSetVisibility(true); 68 | Sleep(); 69 | 70 | VTConsole.WriteLine(); 71 | VTConsole.SetFormat(VTFormat.Underline, VTFormat.Negative); 72 | VTConsole.WriteLine("Press a key to exit !!!", Color.White, Color.Red); 73 | } 74 | 75 | private static void Example3() 76 | { 77 | var plasma = new Plasma(256, 256); 78 | var width = 80; 79 | var height = 40; 80 | 81 | Console.SetWindowSize(width, height); 82 | Console.SetBufferSize(width, height); 83 | Console.SetWindowSize(width, height); // removes bars 84 | Console.Title = "Plasma !"; 85 | Console.CursorVisible = false; 86 | 87 | var builder = new StringBuilder(width * height * 22); 88 | 89 | for (var frame = 0; ; frame++) 90 | { 91 | plasma.PlasmaFrame(frame); 92 | builder.Clear(); 93 | 94 | Thread.Sleep((int)(1.0 / 20 * 1000)); 95 | 96 | for (var i = 0; i < width * height; i++) 97 | { 98 | var x1 = i % width; 99 | var y1 = i / width; 100 | var i1 = y1 * plasma.SizeX + x1; 101 | var b = plasma.Screen[i1]; 102 | 103 | var cr = plasma.ColR[b] >> 4; 104 | var cg = plasma.ColG[b] >> 4; 105 | var cb = plasma.ColB[b] >> 4; 106 | var str = VTConsole.GetColorBackgroundString(cr, cg, cb); 107 | builder.Append(str); 108 | builder.Append(' '); 109 | } 110 | var bytes = Encoding.ASCII.GetBytes(builder.ToString()); 111 | VTConsole.WriteFast(bytes); 112 | } 113 | } 114 | 115 | private static void Sleep(int millisecondsTimeout = 2000) 116 | { 117 | Thread.Sleep(millisecondsTimeout); 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /TrueColorConsoleApp/TrueColorConsoleApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aybe/TrueColorConsole/0f006f4ef14fac7532fe2d1872c7ed636cd57c84/example1.png -------------------------------------------------------------------------------- /example2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aybe/TrueColorConsole/0f006f4ef14fac7532fe2d1872c7ed636cd57c84/example2.png -------------------------------------------------------------------------------- /example3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aybe/TrueColorConsole/0f006f4ef14fac7532fe2d1872c7ed636cd57c84/example3.png -------------------------------------------------------------------------------- /example3.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aybe/TrueColorConsole/0f006f4ef14fac7532fe2d1872c7ed636cd57c84/example3.webm -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aybe/TrueColorConsole/0f006f4ef14fac7532fe2d1872c7ed636cd57c84/icon.png --------------------------------------------------------------------------------