├── App.config
├── Core
├── MathF.cs
├── Enums.cs
├── Examples
│ ├── Primitives.cs
│ ├── ImageConverting.cs
│ └── Raycasting.cs
├── ConsoleListiner.cs
├── NativeMethods.cs
├── Engine.cs
└── ColorUtilites.cs
├── Readme.md
├── Program.cs
├── Properties
└── AssemblyInfo.cs
├── ConsoleGameEngine.csproj
└── .gitignore
/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Core/MathF.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 |
4 | namespace MaximovInk.ConsoleGameEngine.Core
5 | {
6 | public static class MathF
7 | {
8 | public static T Clamp(this T val, T min, T max) where T : IComparable
9 | {
10 | if (val.CompareTo(min) < 0) return min;
11 | else if (val.CompareTo(max) > 0) return max;
12 | else return val;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # ConsoleRenderingEngine
2 | - Can convert RGB colors to console colors , and back.
3 | - Can blend two console colors.
4 | - Can draw basic shapes.
5 | - Contain examples : raycasting , image loading and drawing primitives
6 |
7 | Screenshots:
8 | 
9 | 
10 | 
11 |
12 | Video:
13 |
14 | [](https://www.youtube.com/watch?v=enq7hgUtuYI)
15 |
--------------------------------------------------------------------------------
/Core/Enums.cs:
--------------------------------------------------------------------------------
1 | namespace MaximovInk.ConsoleGameEngine
2 | {
3 | public enum Character : short
4 | {
5 | Null = 0x0000,
6 | Full = 0x00DB,
7 | Dark = 0x00B2,
8 | Medium = 0x00B1,
9 | Light = 0x00B0,
10 | }
11 |
12 | public enum COLOR : short
13 | {
14 | FG_BLACK = 0,
15 | FG_DARK_BLUE = 1,
16 | FG_DARK_GREEN = 2,
17 | FG_DARK_CYAN = 3,
18 | FG_DARK_RED = 4,
19 | FG_DARK_MAGENTA = 5,
20 | FG_DARK_YELLOW = 6,
21 | FG_GREY = 7,
22 | FG_DARK_GREY = 8,
23 | FG_BLUE = 9,
24 | FG_GREEN = 10,
25 | FG_CYAN = 11,
26 | FG_RED = 12,
27 | FG_MAGENTA = 13,
28 | FG_YELLOW = 14,
29 | FG_WHITE = 15,
30 | BG_BLACK = 0,
31 | BG_DARK_BLUE = 16,
32 | BG_DARK_GREEN = 32,
33 | BG_DARK_CYAN = 48,
34 | BG_DARK_RED = 64,
35 | BG_DARK_MAGENTA = 80,
36 | BG_DARK_YELLOW = 96,
37 | BG_GREY = 112,
38 | BG_DARK_GREY = 128,
39 | BG_BLUE = 144,
40 | BG_GREEN = 160,
41 | BG_CYAN = 176,
42 | BG_RED = 192,
43 | BG_MAGENTA = 208,
44 | BG_YELLOW = 224,
45 | BG_WHITE = 240,
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace MaximovInk.ConsoleGameEngine
4 | {
5 | public class Program
6 | {
7 | [STAThread]
8 | private static void Main()
9 | {
10 | bool select = false;
11 |
12 | char Char;
13 | Engine e = new Engine();
14 |
15 | while (select == false)
16 | {
17 | Console.WriteLine("Hello, this is examples.. Write 1 - raycasting ,2 - image loading,3 - primitives to play");
18 |
19 | Char = Console.ReadLine()[0];
20 |
21 | switch (Char)
22 | {
23 | case '1':
24 | e = new Raycasting();
25 | select = true;
26 | break;
27 | case '2':
28 | e = new ImageConverting();
29 | select = true;
30 | break;
31 | case '3':
32 | e = new Primitives();
33 | select = true;
34 | break;
35 | default:
36 | break;
37 | }
38 | }
39 |
40 | e.StartLoop();
41 | }
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // Общие сведения об этой сборке предоставляются следующим набором
6 | // набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
7 | // связанные со сборкой.
8 | [assembly: AssemblyTitle("ConsoleGameEngine")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ConsoleGameEngine")]
13 | [assembly: AssemblyCopyright("Copyright © 2018")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
18 | // для компонентов COM. Если необходимо обратиться к типу в этой сборке через
19 | // COM, задайте атрибуту ComVisible значение TRUE для этого типа.
20 | [assembly: ComVisible(false)]
21 |
22 | // Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
23 | [assembly: Guid("793982aa-527b-419e-a924-01da6da22212")]
24 |
25 | // Сведения о версии сборки состоят из следующих четырех значений:
26 | //
27 | // Основной номер версии
28 | // Дополнительный номер версии
29 | // Номер сборки
30 | // Редакция
31 | //
32 | // Можно задать все значения или принять номер сборки и номер редакции по умолчанию.
33 | // используя "*", как показано ниже:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Core/Examples/Primitives.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace MaximovInk.ConsoleGameEngine
4 | {
5 | public class Primitives : Engine
6 | {
7 | public Primitives(short width = 182, short height = 53, string Title = "Console engine", short fontw = 16, short fonth = 16, bool showFps = true) : base(width, height, Title, fontw, fonth, showFps)
8 | {
9 | }
10 |
11 | protected override void OnStart()
12 | {
13 | //Draw symbol from char
14 | DrawChar(0, 0, '#', 15);
15 | //Draw symbol from short
16 | DrawPixel(2, 0, (short)Character.Medium, (short) (COLOR.FG_BLUE | COLOR.BG_RED));
17 | //Draw line
18 | DrawLine(1, 2, 3, 20, (short)Character.Full, (short)COLOR.FG_CYAN);
19 | //Draw line gradient
20 | DrawLineGradient(3, 2, 5, 20, (short)COLOR.FG_RED, (short)COLOR.FG_BLUE);
21 | //Draw text
22 | DrawText(4, 0, "This is text ..", (short)(COLOR.BG_YELLOW | COLOR.FG_BLUE));
23 | /*
24 | Convert rgb color to ConsoleColor!
25 | */
26 | COLOR cl;
27 | Character ch;
28 | ColorUtilites.GetConsoleColor(Color.Crimson, out ch, out cl);
29 | DrawRect(6, 2, 3, 3, (short)ch, (short)cl);
30 | //Draw rect
31 | DrawRect(11, 2, 4, 4, (short)Character.Full, (short)COLOR.FG_GREEN);
32 | //Draw cicrle
33 | DrawCircle(13, 15, 6,(short)'*', 12);
34 | //Draw triangle
35 | DrawTriangle(21, 41, 25, 0, 0, 25, (short)Character.Dark, (short)COLOR.FG_GREEN);
36 |
37 | FillRect(43, 0, 20, 20, (short)Character.Medium, (short)(COLOR.FG_YELLOW | COLOR.BG_BLUE));
38 |
39 | Apply();
40 | }
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Core/ConsoleListiner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using static MaximovInk.ConsoleGameEngine.Core.NativeMethods;
4 |
5 | namespace MaximovInk.ConsoleGameEngine.Core
6 | {
7 | public static class ConsoleListiner
8 | {
9 | public static event ConsoleMouseEvent MouseEvent;
10 |
11 | public static event ConsoleKeyEvent KeyEvent;
12 |
13 | public static event ConsoleWindowBufferSizeEvent WindowBufferSizeEvent;
14 |
15 | private static bool Run = false;
16 |
17 | public static void Start()
18 | {
19 | if (!Run)
20 | {
21 | Run = true;
22 | IntPtr handleIn = GetStdHandle(STD_INPUT_HANDLE);
23 | new Thread(() =>
24 | {
25 | while (true)
26 | {
27 | uint numRead = 0;
28 | INPUT_RECORD[] record = new INPUT_RECORD[1];
29 | record[0] = new INPUT_RECORD();
30 | ReadConsoleInput(handleIn, record, 1, ref numRead);
31 | if (Run)
32 | switch (record[0].EventType)
33 | {
34 | case INPUT_RECORD.MOUSE_EVENT:
35 | MouseEvent?.Invoke(record[0].MouseEvent);
36 | break;
37 | case INPUT_RECORD.KEY_EVENT:
38 | KeyEvent?.Invoke(record[0].KeyEvent);
39 | break;
40 | case INPUT_RECORD.WINDOW_BUFFER_SIZE_EVENT:
41 | WindowBufferSizeEvent?.Invoke(record[0].WindowBufferSizeEvent);
42 | break;
43 | }
44 | else
45 | {
46 | uint numWritten = 0;
47 | WriteConsoleInput(handleIn, record, 1, ref numWritten);
48 | return;
49 | }
50 | }
51 | }).Start();
52 | }
53 | }
54 |
55 | public static void Stop() => Run = false;
56 |
57 | public delegate void ConsoleMouseEvent(MOUSE_EVENT_RECORD r);
58 |
59 | public delegate void ConsoleKeyEvent(KEY_EVENT_RECORD r);
60 |
61 | public delegate void ConsoleWindowBufferSizeEvent(WINDOW_BUFFER_SIZE_RECORD r);
62 |
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Core/Examples/ImageConverting.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Drawing.Drawing2D;
4 | using System.Drawing.Imaging;
5 |
6 | namespace MaximovInk.ConsoleGameEngine
7 | {
8 | public class ImageConverting : Engine
9 | {
10 | private Bitmap bitmap;
11 |
12 | public ImageConverting(short width = 460, short height = 150, string Title = "Raycasting", short fontw = 6, short fonth = 6, bool showFps = true)
13 | : base(width, height, Title, fontw, fonth, showFps)
14 | {
15 | }
16 |
17 | protected override void OnStart()
18 | {
19 | var b = new Bitmap("image.jpg");
20 | bitmap = (Bitmap)FixedSize(b, Height, Width, false);
21 |
22 | for (int x = 0; x < bitmap.Width; x++)
23 | {
24 | for (int y = 0; y < bitmap.Height; y++)
25 | {
26 | Character ch = Character.Full;
27 | COLOR color = COLOR.FG_WHITE;
28 | ColorUtilites.GetConsoleColor(bitmap.GetPixel(x, y), out ch, out color);
29 |
30 | DrawPixel((short)x, (short)y, (short)ch, (short)color);
31 | }
32 | }
33 |
34 | Apply();
35 |
36 | }
37 |
38 | public static Image FixedSize(Image imgPhoto, int Height, int Width, bool needToFill)
39 | {
40 | int sourceWidth = imgPhoto.Width;
41 | int sourceHeight = imgPhoto.Height;
42 | int sourceX = 0;
43 | int sourceY = 0;
44 | int destX = 0;
45 | int destY = 0;
46 |
47 | float nPercent = 0;
48 | float nPercentW = 0;
49 | float nPercentH = 0;
50 |
51 | nPercentW = (Width / (float)sourceWidth);
52 | nPercentH = (Height / (float)sourceHeight);
53 | if (!needToFill)
54 | {
55 | if (nPercentH < nPercentW)
56 | {
57 | nPercent = nPercentH;
58 | }
59 | else
60 | {
61 | nPercent = nPercentW;
62 | }
63 | }
64 | else
65 | {
66 | if (nPercentH > nPercentW)
67 | {
68 | nPercent = nPercentH;
69 | destX = (int)Math.Round((Width -
70 | (sourceWidth * nPercent)) / 2);
71 | }
72 | else
73 | {
74 | nPercent = nPercentW;
75 | destY = (int)Math.Round((Height -
76 | (sourceHeight * nPercent)) / 2);
77 | }
78 | }
79 |
80 | if (nPercent > 1)
81 | nPercent = 1;
82 |
83 | int destWidth = (int)Math.Round(sourceWidth * nPercent);
84 | int destHeight = (int)Math.Round(sourceHeight * nPercent);
85 |
86 | Bitmap bmPhoto = new Bitmap(
87 | destWidth <= Width ? destWidth : Width,
88 | destHeight < Height ? destHeight : Height,
89 | PixelFormat.Format32bppRgb);
90 |
91 | Graphics grPhoto = Graphics.FromImage(bmPhoto);
92 | grPhoto.Clear(Color.White);
93 | grPhoto.InterpolationMode = InterpolationMode.Default;
94 | grPhoto.CompositingQuality = CompositingQuality.HighQuality;
95 | grPhoto.SmoothingMode = SmoothingMode.HighQuality;
96 |
97 | grPhoto.DrawImage(imgPhoto,
98 | new Rectangle(destX, destY, destWidth, destHeight),
99 | new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
100 | GraphicsUnit.Pixel);
101 |
102 | grPhoto.Dispose();
103 | return bmPhoto;
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/ConsoleGameEngine.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {793982AA-527B-419E-A924-01DA6DA22212}
8 | Exe
9 | MaximovInk.ConsoleGameEngine
10 | ConsoleGameEngine
11 | v4.7.1
12 | 512
13 | true
14 | true
15 | publish\
16 | true
17 | Disk
18 | false
19 | Foreground
20 | 7
21 | Days
22 | false
23 | false
24 | true
25 | 0
26 | 1.0.0.%2a
27 | false
28 | false
29 | true
30 |
31 |
32 | AnyCPU
33 | true
34 | full
35 | false
36 | bin\Debug\
37 | DEBUG;TRACE
38 | prompt
39 | 4
40 | false
41 |
42 |
43 | AnyCPU
44 | pdbonly
45 | true
46 | bin\Release\
47 | TRACE
48 | prompt
49 | 4
50 |
51 |
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 | False
81 | Microsoft .NET Framework 4.7.1 %28x86 и x64%29
82 | true
83 |
84 |
85 | False
86 | .NET Framework 3.5 SP1
87 | false
88 |
89 |
90 |
91 |
92 | PreserveNewest
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015/2017 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # Visual Studio 2017 auto generated files
33 | Generated\ Files/
34 |
35 | # MSTest test Results
36 | [Tt]est[Rr]esult*/
37 | [Bb]uild[Ll]og.*
38 |
39 | # NUNIT
40 | *.VisualState.xml
41 | TestResult.xml
42 |
43 | # Build Results of an ATL Project
44 | [Dd]ebugPS/
45 | [Rr]eleasePS/
46 | dlldata.c
47 |
48 | # Benchmark Results
49 | BenchmarkDotNet.Artifacts/
50 |
51 | # .NET Core
52 | project.lock.json
53 | project.fragment.lock.json
54 | artifacts/
55 | **/Properties/launchSettings.json
56 |
57 | # StyleCop
58 | StyleCopReport.xml
59 |
60 | # Files built by Visual Studio
61 | *_i.c
62 | *_p.c
63 | *_i.h
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.iobj
68 | *.pch
69 | *.pdb
70 | *.ipdb
71 | *.pgc
72 | *.pgd
73 | *.rsp
74 | *.sbr
75 | *.tlb
76 | *.tli
77 | *.tlh
78 | *.tmp
79 | *.tmp_proj
80 | *.log
81 | *.vspscc
82 | *.vssscc
83 | .builds
84 | *.pidb
85 | *.svclog
86 | *.scc
87 |
88 | # Chutzpah Test files
89 | _Chutzpah*
90 |
91 | # Visual C++ cache files
92 | ipch/
93 | *.aps
94 | *.ncb
95 | *.opendb
96 | *.opensdf
97 | *.sdf
98 | *.cachefile
99 | *.VC.db
100 | *.VC.VC.opendb
101 |
102 | # Visual Studio profiler
103 | *.psess
104 | *.vsp
105 | *.vspx
106 | *.sap
107 |
108 | # Visual Studio Trace Files
109 | *.e2e
110 |
111 | # TFS 2012 Local Workspace
112 | $tf/
113 |
114 | # Guidance Automation Toolkit
115 | *.gpState
116 |
117 | # ReSharper is a .NET coding add-in
118 | _ReSharper*/
119 | *.[Rr]e[Ss]harper
120 | *.DotSettings.user
121 |
122 | # JustCode is a .NET coding add-in
123 | .JustCode
124 |
125 | # TeamCity is a build add-in
126 | _TeamCity*
127 |
128 | # DotCover is a Code Coverage Tool
129 | *.dotCover
130 |
131 | # AxoCover is a Code Coverage Tool
132 | .axoCover/*
133 | !.axoCover/settings.json
134 |
135 | # Visual Studio code coverage results
136 | *.coverage
137 | *.coveragexml
138 |
139 | # NCrunch
140 | _NCrunch_*
141 | .*crunch*.local.xml
142 | nCrunchTemp_*
143 |
144 | # MightyMoose
145 | *.mm.*
146 | AutoTest.Net/
147 |
148 | # Web workbench (sass)
149 | .sass-cache/
150 |
151 | # Installshield output folder
152 | [Ee]xpress/
153 |
154 | # DocProject is a documentation generator add-in
155 | DocProject/buildhelp/
156 | DocProject/Help/*.HxT
157 | DocProject/Help/*.HxC
158 | DocProject/Help/*.hhc
159 | DocProject/Help/*.hhk
160 | DocProject/Help/*.hhp
161 | DocProject/Help/Html2
162 | DocProject/Help/html
163 |
164 | # Click-Once directory
165 | publish/
166 |
167 | # Publish Web Output
168 | *.[Pp]ublish.xml
169 | *.azurePubxml
170 | # Note: Comment the next line if you want to checkin your web deploy settings,
171 | # but database connection strings (with potential passwords) will be unencrypted
172 | *.pubxml
173 | *.publishproj
174 |
175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
176 | # checkin your Azure Web App publish settings, but sensitive information contained
177 | # in these scripts will be unencrypted
178 | PublishScripts/
179 |
180 | # NuGet Packages
181 | *.nupkg
182 | # The packages folder can be ignored because of Package Restore
183 | **/[Pp]ackages/*
184 | # except build/, which is used as an MSBuild target.
185 | !**/[Pp]ackages/build/
186 | # Uncomment if necessary however generally it will be regenerated when needed
187 | #!**/[Pp]ackages/repositories.config
188 | # NuGet v3's project.json files produces more ignorable files
189 | *.nuget.props
190 | *.nuget.targets
191 |
192 | # Microsoft Azure Build Output
193 | csx/
194 | *.build.csdef
195 |
196 | # Microsoft Azure Emulator
197 | ecf/
198 | rcf/
199 |
200 | # Windows Store app package directories and files
201 | AppPackages/
202 | BundleArtifacts/
203 | Package.StoreAssociation.xml
204 | _pkginfo.txt
205 | *.appx
206 |
207 | # Visual Studio cache files
208 | # files ending in .cache can be ignored
209 | *.[Cc]ache
210 | # but keep track of directories ending in .cache
211 | !*.[Cc]ache/
212 |
213 | # Others
214 | ClientBin/
215 | ~$*
216 | *~
217 | *.dbmdl
218 | *.dbproj.schemaview
219 | *.jfm
220 | *.pfx
221 | *.publishsettings
222 | orleans.codegen.cs
223 |
224 | # Including strong name files can present a security risk
225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
226 | #*.snk
227 |
228 | # Since there are multiple workflows, uncomment next line to ignore bower_components
229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
230 | #bower_components/
231 |
232 | # RIA/Silverlight projects
233 | Generated_Code/
234 |
235 | # Backup & report files from converting an old project file
236 | # to a newer Visual Studio version. Backup files are not needed,
237 | # because we have git ;-)
238 | _UpgradeReport_Files/
239 | Backup*/
240 | UpgradeLog*.XML
241 | UpgradeLog*.htm
242 | ServiceFabricBackup/
243 | *.rptproj.bak
244 |
245 | # SQL Server files
246 | *.mdf
247 | *.ldf
248 | *.ndf
249 |
250 | # Business Intelligence projects
251 | *.rdl.data
252 | *.bim.layout
253 | *.bim_*.settings
254 | *.rptproj.rsuser
255 |
256 | # Microsoft Fakes
257 | FakesAssemblies/
258 |
259 | # GhostDoc plugin setting file
260 | *.GhostDoc.xml
261 |
262 | # Node.js Tools for Visual Studio
263 | .ntvs_analysis.dat
264 | node_modules/
265 |
266 | # Visual Studio 6 build log
267 | *.plg
268 |
269 | # Visual Studio 6 workspace options file
270 | *.opt
271 |
272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
273 | *.vbw
274 |
275 | # Visual Studio LightSwitch build output
276 | **/*.HTMLClient/GeneratedArtifacts
277 | **/*.DesktopClient/GeneratedArtifacts
278 | **/*.DesktopClient/ModelManifest.xml
279 | **/*.Server/GeneratedArtifacts
280 | **/*.Server/ModelManifest.xml
281 | _Pvt_Extensions
282 |
283 | # Paket dependency manager
284 | .paket/paket.exe
285 | paket-files/
286 |
287 | # FAKE - F# Make
288 | .fake/
289 |
290 | # JetBrains Rider
291 | .idea/
292 | *.sln.iml
293 |
294 | # CodeRush
295 | .cr/
296 |
297 | # Python Tools for Visual Studio (PTVS)
298 | __pycache__/
299 | *.pyc
300 |
301 | # Cake - Uncomment if you are using it
302 | # tools/**
303 | # !tools/packages.config
304 |
305 | # Tabs Studio
306 | *.tss
307 |
308 | # Telerik's JustMock configuration file
309 | *.jmconfig
310 |
311 | # BizTalk build output
312 | *.btp.cs
313 | *.btm.cs
314 | *.odx.cs
315 | *.xsd.cs
316 |
317 | # OpenCover UI analysis results
318 | OpenCover/
319 |
320 | # Azure Stream Analytics local run output
321 | ASALocalRun/
322 |
323 | # MSBuild Binary and Structured Log
324 | *.binlog
325 |
326 | # NVidia Nsight GPU debugger configuration file
327 | *.nvuser
328 |
329 | # MFractors (Xamarin productivity tool) working folder
330 | .mfractor/
331 |
--------------------------------------------------------------------------------
/Core/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace MaximovInk.ConsoleGameEngine.Core
5 | {
6 | public static class NativeMethods
7 | {
8 | public const int STDIN = -10;
9 | public const int STDOUT = -11;
10 | public const int STDERR = -12;
11 | public static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
12 |
13 | public struct COORD
14 | {
15 | public short X;
16 | public short Y;
17 |
18 | public COORD(short x, short y)
19 | {
20 | X = x;
21 | Y = y;
22 | }
23 | }
24 |
25 | [StructLayout(LayoutKind.Explicit)]
26 | public struct INPUT_RECORD
27 | {
28 | public const ushort KEY_EVENT = 0x0001,
29 | MOUSE_EVENT = 0x0002,
30 | WINDOW_BUFFER_SIZE_EVENT = 0x0004; //more
31 |
32 | [FieldOffset(0)]
33 | public ushort EventType;
34 | [FieldOffset(4)]
35 | public KEY_EVENT_RECORD KeyEvent;
36 | [FieldOffset(4)]
37 | public MOUSE_EVENT_RECORD MouseEvent;
38 | [FieldOffset(4)]
39 | public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
40 | /*
41 | and:
42 | MENU_EVENT_RECORD MenuEvent;
43 | FOCUS_EVENT_RECORD FocusEvent;
44 | */
45 | }
46 |
47 | [StructLayout(LayoutKind.Sequential)]
48 | public struct CONSOLE_SCREEN_BUFFER_INFO
49 | {
50 | public COORD dwSize;
51 | public COORD dwCursorPosition;
52 | public short wAttributes;
53 | public SmallRect srWindow;
54 | public COORD dwMaximumWindowSize;
55 | }
56 |
57 | [StructLayout(LayoutKind.Explicit)]
58 | public struct CharInfo
59 | {
60 | [FieldOffset(0)]
61 | internal char UnicodeChar;
62 | [FieldOffset(0)]
63 | internal short AsciiChar;
64 | [FieldOffset(2)]
65 | internal short Attributes;
66 | }
67 |
68 | [StructLayout(LayoutKind.Sequential)]
69 | public struct SmallRect
70 | {
71 | public short Left;
72 | public short Top;
73 | public short Right;
74 | public short Bottom;
75 | }
76 |
77 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
78 | public struct CONSOLE_FONT_INFO_EX
79 | {
80 | public uint cbSize;
81 | public uint nFont;
82 | public COORD dwFontSize;
83 | public int FontFamily;
84 | public int FontWeight;
85 |
86 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
87 | public string FaceName;
88 | }
89 |
90 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
91 | public struct CONSOLE_FONT_INFOEX
92 | {
93 | public uint cbSize;
94 | public uint nFont;
95 | public COORD dwFontSize;
96 | public int FontFamily;
97 | public int FontWeight;
98 |
99 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
100 | public string FaceName;
101 | }
102 |
103 | public struct MOUSE_EVENT_RECORD
104 | {
105 | public COORD dwMousePosition;
106 |
107 | public const uint FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001,
108 | FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004,
109 | FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008,
110 | FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010,
111 | RIGHTMOST_BUTTON_PRESSED = 0x0002;
112 | public uint dwButtonState;
113 |
114 | public const int CAPSLOCK_ON = 0x0080,
115 | ENHANCED_KEY = 0x0100,
116 | LEFT_ALT_PRESSED = 0x0002,
117 | LEFT_CTRL_PRESSED = 0x0008,
118 | NUMLOCK_ON = 0x0020,
119 | RIGHT_ALT_PRESSED = 0x0001,
120 | RIGHT_CTRL_PRESSED = 0x0004,
121 | SCROLLLOCK_ON = 0x0040,
122 | SHIFT_PRESSED = 0x0010;
123 | public uint dwControlKeyState;
124 |
125 | public const int DOUBLE_CLICK = 0x0002,
126 | MOUSE_HWHEELED = 0x0008,
127 | MOUSE_MOVED = 0x0001,
128 | MOUSE_WHEELED = 0x0004;
129 | public uint dwEventFlags;
130 | }
131 |
132 | [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
133 | public struct KEY_EVENT_RECORD
134 | {
135 | [FieldOffset(0)]
136 | public bool bKeyDown;
137 | [FieldOffset(4)]
138 | public ushort wRepeatCount;
139 | [FieldOffset(6)]
140 | public ushort wVirtualKeyCode;
141 | [FieldOffset(8)]
142 | public ushort wVirtualScanCode;
143 | [FieldOffset(10)]
144 | public char UnicodeChar;
145 | [FieldOffset(10)]
146 | public byte AsciiChar;
147 |
148 | public const int CAPSLOCK_ON = 0x0080,
149 | ENHANCED_KEY = 0x0100,
150 | LEFT_ALT_PRESSED = 0x0002,
151 | LEFT_CTRL_PRESSED = 0x0008,
152 | NUMLOCK_ON = 0x0020,
153 | RIGHT_ALT_PRESSED = 0x0001,
154 | RIGHT_CTRL_PRESSED = 0x0004,
155 | SCROLLLOCK_ON = 0x0040,
156 | SHIFT_PRESSED = 0x0010;
157 | [FieldOffset(12)]
158 | public uint dwControlKeyState;
159 | }
160 |
161 | public struct WINDOW_BUFFER_SIZE_RECORD
162 | {
163 | public COORD dwSize;
164 | }
165 |
166 | public const uint STD_INPUT_HANDLE = unchecked((uint)-10),
167 | STD_OUTPUT_HANDLE = unchecked((uint)-11),
168 | STD_ERROR_HANDLE = unchecked((uint)-12);
169 |
170 | [DllImport("kernel32.dll")]
171 | public static extern IntPtr GetStdHandle(uint nStdHandle);
172 |
173 | [Flags]
174 | public enum ConsoleModes : uint
175 | {
176 | ENABLE_PROCESSED_INPUT = 0x0001,
177 | ENABLE_LINE_INPUT = 0x0002,
178 | ENABLE_ECHO_INPUT = 0x0004,
179 | ENABLE_WINDOW_INPUT = 0x0008,
180 | ENABLE_MOUSE_INPUT = 0x0010,
181 | ENABLE_INSERT_MODE = 0x0020,
182 | ENABLE_QUICK_EDIT_MODE = 0x0040,
183 | ENABLE_EXTENDED_FLAGS = 0x0080,
184 | ENABLE_AUTO_POSITION = 0x0100,
185 |
186 | ENABLE_PROCESSED_OUTPUT = 0x0001,
187 | ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002,
188 | ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004,
189 | DISABLE_NEWLINE_AUTO_RETURN = 0x0008,
190 | ENABLE_LVB_GRID_WORLDWIDE = 0x0010
191 | }
192 |
193 | /* public const uint ENABLE_MOUSE_INPUT = 0x0010,
194 | ENABLE_QUICK_EDIT_MODE = 0x0040,
195 | ENABLE_EXTENDED_FLAGS = 0x0080,
196 | ENABLE_ECHO_INPUT = 0x0004,
197 | ENABLE_WINDOW_INPUT = 0x0008; //more*/
198 |
199 | [DllImport("kernel32.dll")]
200 | public static extern bool GetConsoleMode(IntPtr hConsoleInput, ref uint lpMode);
201 |
202 | [DllImport("kernel32.dll")]
203 | public static extern bool SetConsoleMode(IntPtr hConsoleInput, uint dwMode);
204 |
205 |
206 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
207 | public static extern bool ReadConsoleInput(IntPtr hConsoleInput, [Out] INPUT_RECORD[] lpBuffer, uint nLength, ref uint lpNumberOfEventsRead);
208 |
209 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
210 | public static extern bool WriteConsoleInput(IntPtr hConsoleInput, INPUT_RECORD[] lpBuffer, uint nLength, ref uint lpNumberOfEventsWritten);
211 |
212 |
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/Core/Examples/Raycasting.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using static MaximovInk.ConsoleGameEngine.Core.NativeMethods;
3 |
4 | namespace MaximovInk.ConsoleGameEngine
5 | {
6 | public class Raycasting : Engine
7 | {
8 | private short w = 24;
9 | private short h = 24;
10 |
11 | private float scaleX;
12 | private float scaleY;
13 |
14 | private float lastMousePosX = 0;
15 |
16 | private int[,] worldMap = new int[,]
17 | {
18 | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
19 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
20 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
21 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
22 | {1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
23 | {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
24 | {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1},
25 | {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
26 | {1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
27 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
28 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
29 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
30 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
31 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
32 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
33 | {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
34 | {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
35 | {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
36 | {1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
37 | {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
38 | {1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
39 | {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
40 | {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
41 | {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
42 | };
43 |
44 | double posX = 22, posY = 12; //x and y start position
45 | double dirX = -1, dirY = 0; //initial direction vector
46 | double planeX = 0, planeY = 0.66; //the 2d raycaster version of camera plane
47 |
48 | public Raycasting(short width = 840/2, short height = 254/2, string Title = "Console engine", short fontw = 4, short fonth = 4, bool showFps = true) : base(width, height, Title, fontw, fonth, showFps)
49 | {
50 | }
51 |
52 | protected override void OnDraw()
53 | {
54 | Clear();
55 | for (int x = 0; x < w; x++)
56 | {
57 | //calculate ray position and direction
58 | double cameraX = 2 * x / (double)w - 1; //x-coordinate in camera space
59 | double rayDirX = dirX + planeX * cameraX;
60 | double rayDirY = dirY + planeY * cameraX;
61 | //which box of the map we're in
62 | int mapX = (int)posX;
63 | int mapY = (int)posY;
64 |
65 | //length of ray from current position to next x or y-side
66 | double sideDistX;
67 | double sideDistY;
68 |
69 | //length of ray from one x or y-side to next x or y-side
70 | double deltaDistX = Math.Abs(1 / rayDirX);
71 | double deltaDistY = Math.Abs(1 / rayDirY);
72 | double perpWallDist;
73 |
74 | //what direction to step in x or y-direction (either +1 or -1)
75 | int stepX;
76 | int stepY;
77 |
78 | int hit = 0; //was there a wall hit?
79 | int side = 0; //was a NS or a EW wall hit?
80 |
81 | if (rayDirX < 0)
82 | {
83 | stepX = -1;
84 | sideDistX = (posX - mapX) * deltaDistX;
85 | }
86 | else
87 | {
88 | stepX = 1;
89 | sideDistX = (mapX + 1.0 - posX) * deltaDistX;
90 | }
91 | if (rayDirY < 0)
92 | {
93 | stepY = -1;
94 | sideDistY = (posY - mapY) * deltaDistY;
95 | }
96 | else
97 | {
98 | stepY = 1;
99 | sideDistY = (mapY + 1.0 - posY) * deltaDistY;
100 | }
101 |
102 | while (hit == 0)
103 | {
104 | if (sideDistX < sideDistY)
105 | {
106 | sideDistX += deltaDistX;
107 | mapX += stepX;
108 | side = 0;
109 | }
110 | else
111 | {
112 | sideDistY += deltaDistY;
113 | mapY += stepY;
114 | side = 1;
115 | }
116 |
117 | if (worldMap[mapX,mapY] > 0) hit = 1;
118 | }
119 |
120 | if (side == 0) perpWallDist = (mapX - posX + (1 - stepX) / 2) / rayDirX;
121 | else perpWallDist = (mapY - posY + (1 - stepY) / 2) / rayDirY;
122 |
123 | int lineHeight = (int)(h / perpWallDist);
124 |
125 | int drawStart = -lineHeight / 2 + h / 2;
126 | if (drawStart < 0) drawStart = 0;
127 | int drawEnd = lineHeight / 2 + h / 2;
128 | if (drawEnd >= h) drawEnd = h - 1;
129 |
130 | COLOR color;
131 | Character character = Character.Full;
132 |
133 | switch (worldMap[mapX,mapY])
134 | {
135 | case 1: color = COLOR.FG_RED; break;
136 | case 2: color = COLOR.FG_GREEN; break;
137 | case 3: color = COLOR.FG_BLUE; break;
138 | case 4: color = COLOR.FG_WHITE; break;
139 | default: color = COLOR.FG_YELLOW; break;
140 | }
141 |
142 | if (side == 1) { character = Character.Medium; }
143 |
144 |
145 |
146 | DrawLine((short)x, (short)drawStart, (short)x, (short)drawEnd, (short)character, (short)color);
147 |
148 | }
149 |
150 | Apply();
151 | }
152 |
153 | protected override void OnKey(KEY_EVENT_RECORD e)
154 | {
155 | double moveSpeed = 5.0 * elapsed;
156 |
157 | if (e.bKeyDown == true)
158 | {
159 | if (e.UnicodeChar == 'w')
160 | {
161 | if (posX + dirX * moveSpeed > 0 && posX + dirX * moveSpeed < worldMap.GetLength(0))
162 | {
163 | if (worldMap[(int)(posX + dirX * moveSpeed), (int)posY] == 0) posX += dirX * moveSpeed;
164 | if (worldMap[(int)(posX), (int)(posY + dirY * moveSpeed)] == 0) posY += dirY * moveSpeed;
165 | }
166 | }
167 | if (e.UnicodeChar == 's')
168 | {
169 | if (posX - dirX * moveSpeed > 0 && posX - dirX * moveSpeed < worldMap.GetLength(0))
170 | {
171 | if (worldMap[(int)(posX - dirX * moveSpeed), (int)posY] == 0) posX -= dirX * moveSpeed;
172 | if (worldMap[(int)(posX), (int)(posY - dirY * moveSpeed)] == 0) posY -= dirY * moveSpeed;
173 | }
174 |
175 | }
176 | }
177 | }
178 |
179 | protected override void OnMouse(MOUSE_EVENT_RECORD m)
180 | {
181 | double rotSpeed = 3.0 * elapsed;
182 | if (m.dwMousePosition.X != lastMousePosX )
183 | {
184 | float deltaX = m.dwMousePosition.X - lastMousePosX;
185 | lastMousePosX = m.dwMousePosition.X;
186 | if (deltaX > 0)
187 | {
188 | double oldDirX = dirX;
189 | dirX = dirX * Math.Cos(-rotSpeed) - dirY * Math.Sin(-rotSpeed);
190 | dirY = oldDirX * Math.Sin(-rotSpeed) + dirY * Math.Cos(-rotSpeed);
191 | double oldPlaneX = planeX;
192 | planeX = planeX * Math.Cos(-rotSpeed) - planeY * Math.Sin(-rotSpeed);
193 | planeY = oldPlaneX * Math.Sin(-rotSpeed) + planeY * Math.Cos(-rotSpeed);
194 | }
195 | else
196 | {
197 | double oldDirX = dirX;
198 | dirX = dirX * Math.Cos(rotSpeed) - dirY * Math.Sin(rotSpeed);
199 | dirY = oldDirX * Math.Sin(rotSpeed) + dirY * Math.Cos(rotSpeed);
200 | double oldPlaneX = planeX;
201 | planeX = planeX * Math.Cos(rotSpeed) - planeY * Math.Sin(rotSpeed);
202 | planeY = oldPlaneX * Math.Sin(rotSpeed) + planeY * Math.Cos(rotSpeed);
203 | }
204 | }
205 |
206 | }
207 |
208 | protected override void OnStart()
209 | {
210 | scaleX = Width / w;
211 | scaleY = Height / h;
212 |
213 | w *= (short)scaleX;
214 | h *= (short)scaleY;
215 | }
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/Core/Engine.cs:
--------------------------------------------------------------------------------
1 | using MaximovInk.ConsoleGameEngine.Core;
2 | using System;
3 | using System.Diagnostics;
4 | using System.Drawing;
5 | using System.Runtime.InteropServices;
6 | using System.Threading;
7 | using static MaximovInk.ConsoleGameEngine.Core.NativeMethods;
8 |
9 | namespace MaximovInk.ConsoleGameEngine
10 | {
11 | public class Engine
12 | {
13 | public short Width { get; protected set; }
14 | public short Height { get; protected set; }
15 | public CharInfo[] buffer;
16 | protected SmallRect rect;
17 |
18 | public bool isRun = false;
19 |
20 | protected Thread Thread;
21 | protected float elapsed { get; private set; }
22 | private Stopwatch sw;
23 |
24 | protected string title;
25 |
26 | protected bool ShowFPS = true;
27 | protected bool CountFrameRate = true;
28 |
29 | public Engine(short width = 240, short height = 80 , string Title ="Console engine", short fontw = 12, short fonth = 12, bool showFps = true )
30 | {
31 | Width = width;
32 | Height = height;
33 | SetConsoleCP(437);
34 | SetConsoleOutputCP(437);
35 | buffer = new CharInfo[Width * Height];
36 |
37 | rect = new SmallRect() { Left = 0, Top = 0, Right = Width, Bottom = Height };
38 | Console.CursorVisible = false;
39 | Console.SetWindowPosition(0, 0);
40 |
41 | CONSOLE_FONT_INFO_EX ConsoleFontInfo = new CONSOLE_FONT_INFO_EX();
42 | ConsoleFontInfo.cbSize = (uint)Marshal.SizeOf(ConsoleFontInfo);
43 | ConsoleFontInfo.FaceName = "Lucida Console";
44 | ConsoleFontInfo.dwFontSize.X = fontw;
45 | ConsoleFontInfo.dwFontSize.Y = fonth;
46 |
47 | SetCurrentConsoleFontEx(GetStdHandle(STDOUT), false, ref ConsoleFontInfo);
48 |
49 | IntPtr inHandle = GetStdHandle(STDIN);
50 | uint mode = 0;
51 | GetConsoleMode(inHandle, ref mode);
52 | //mode &= ~ENABLE_QUICK_EDIT_MODE;
53 | mode |= (uint)ConsoleModes.ENABLE_WINDOW_INPUT;
54 | mode |= (uint)ConsoleModes.ENABLE_MOUSE_INPUT;
55 | mode &= ~(uint)ConsoleModes.ENABLE_QUICK_EDIT_MODE;
56 |
57 |
58 | SetConsoleMode(inHandle, mode);
59 |
60 | Console.SetWindowSize(width, height);
61 | Console.SetBufferSize(width, height);
62 |
63 | ShowFPS = showFps;
64 |
65 | Console.Title = Title;
66 | title = Title;
67 | }
68 |
69 | public void StartLoop()
70 | {
71 | isRun = true;
72 | Thread = new Thread(GameThread);
73 | Thread.Priority = ThreadPriority.Highest;
74 | sw = new Stopwatch();
75 | ConsoleListiner.Start();
76 | ConsoleListiner.KeyEvent += OnKey;
77 | ConsoleListiner.MouseEvent += OnMouse;
78 | OnStart();
79 | Thread.Start();
80 | }
81 |
82 | private void GameThread()
83 | {
84 | while (isRun)
85 | {
86 | bool f = CountFrameRate;
87 | if (f)
88 | {
89 | sw.Start();
90 | }
91 |
92 | OnUpdate();
93 | OnDraw();
94 | if (ShowFPS)
95 | {
96 | Debug.WriteLine("GGG");
97 | DrawText(0, 0, "FPS:" + (1 / elapsed), 1);
98 | }
99 |
100 | if (f)
101 | {
102 | elapsed = (float)sw.Elapsed.TotalSeconds;
103 | sw.Stop();
104 | sw.Reset();
105 | }
106 | }
107 | ConsoleListiner.Stop();
108 | ConsoleListiner.KeyEvent -= OnKey;
109 | ConsoleListiner.MouseEvent -= OnMouse;
110 | }
111 |
112 | protected virtual void OnKey(KEY_EVENT_RECORD e)
113 | {
114 |
115 | }
116 |
117 | protected virtual void OnMouse(MOUSE_EVENT_RECORD m)
118 | {
119 |
120 | }
121 |
122 | public void DrawTriangle(short x1, short x2, short x3 , short y1, short y2, short y3, short character, short color)
123 | {
124 | DrawLine(x1, y1, x2, y2,character,color);
125 | DrawLine(x1, y1, x3, y3,character,color);
126 | DrawLine(x2, y2, x3, y3, character, color);
127 | }
128 |
129 | public void DrawRect(short x, short y, short width, short height, short character, short color)
130 | {
131 | DrawLine(x, y, x, (short)(height + y), character, color);
132 | DrawLine(x, y, (short)(width + x), y, character, color);
133 | DrawLine(x, (short)(y+height), (short)(width + x), (short)(height + y), character, color);
134 | DrawLine((short)(x+width), y, (short)(width + x), (short)(height + y), character, color);
135 | }
136 |
137 | public void DrawCircle(short x0, short y0, short radius, short character, short color)
138 | {
139 | int x = 0, y = radius;
140 | int d = 3 - 2 * radius;
141 |
142 | DrawCircle(x0, (short)x, y0, (short)y, character, color);
143 |
144 | while (y >= x)
145 | {
146 | x++;
147 | if (d > 0)
148 | {
149 | y--;
150 | d = d + 4 * (x - y) + 10;
151 | }
152 | else
153 | d = d + 4 * x + 6;
154 |
155 | DrawCircle(x0, (short)x, y0, (short)y, character, color);
156 | }
157 |
158 | }
159 |
160 | private void DrawCircle(short x0, short x, short y0, short y , short character , short color)
161 | {
162 | DrawPixel((short)(x0 + x), (short)(y0 + y), character, color);
163 | DrawPixel((short)(x0 - x), (short)(y0 + y), character, color);
164 | DrawPixel((short)(x0 + x), (short)(y0 - y), character, color);
165 | DrawPixel((short)(x0 - x), (short)(y0 - y), character, color);
166 | DrawPixel((short)(x0 + y), (short)(y0 + x), character, color);
167 | DrawPixel((short)(x0 - y), (short)(y0 + x), character, color);
168 | DrawPixel((short)(x0 + y), (short)(y0 - x), character, color);
169 | DrawPixel((short)(x0 - y), (short)(y0 - x), character, color);
170 | }
171 |
172 | public void DrawLineGradient(short x, short y, short x2, short y2, short color1, short color2)
173 | {
174 | int w = x2 - x;
175 | int h = y2 - y;
176 | short dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
177 | if (w < 0) dx1 = -1; else if (w > 0) dx1 = 1;
178 | if (h < 0) dy1 = -1; else if (h > 0) dy1 = 1;
179 | if (w < 0) dx2 = -1; else if (w > 0) dx2 = 1;
180 | int longest = Math.Abs(w);
181 | int shortest = Math.Abs(h);
182 | if (!(longest > shortest))
183 | {
184 | longest = Math.Abs(h);
185 | shortest = Math.Abs(w);
186 | if (h < 0) dy2 = -1; else if (h > 0) dy2 = 1;
187 | dx2 = 0;
188 | }
189 | int numerator = longest >> 1;
190 |
191 | Color one = ((COLOR)color1).GetRGB();
192 | Color two = ((COLOR)color2).GetRGB();
193 |
194 | for (int i = 0; i <= longest; i++)
195 | {
196 | COLOR cl;
197 | Character ch;
198 |
199 | ColorUtilites.CombineTwoColors(((COLOR)color1), ((COLOR)color2), (float)i / longest, out ch, out cl);
200 |
201 | DrawPixel(x, y, (short)ch, (short)cl);
202 | numerator += shortest;
203 | if (!(numerator < longest))
204 | {
205 | numerator -= longest;
206 | x += dx1;
207 | y += dy1;
208 | }
209 | else
210 | {
211 | x += dx2;
212 | y += dy2;
213 | }
214 |
215 | }
216 | }
217 |
218 | public void DrawLine(short x, short y, short x2, short y2, short character, short color)
219 | {
220 | int w = x2 - x;
221 | int h = y2 - y;
222 | short dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
223 | if (w < 0) dx1 = -1; else if (w > 0) dx1 = 1;
224 | if (h < 0) dy1 = -1; else if (h > 0) dy1 = 1;
225 | if (w < 0) dx2 = -1; else if (w > 0) dx2 = 1;
226 | int longest = Math.Abs(w);
227 | int shortest = Math.Abs(h);
228 | if (!(longest > shortest))
229 | {
230 | longest = Math.Abs(h);
231 | shortest = Math.Abs(w);
232 | if (h < 0) dy2 = -1; else if (h > 0) dy2 = 1;
233 | dx2 = 0;
234 | }
235 | int numerator = longest >> 1;
236 | for (int i = 0; i <= longest; i++)
237 | {
238 | DrawPixel(x, y, character, color);
239 | numerator += shortest;
240 | if (!(numerator < longest))
241 | {
242 | numerator -= longest;
243 | x += dx1;
244 | y += dy1;
245 | }
246 | else
247 | {
248 | x += dx2;
249 | y += dy2;
250 | }
251 | }
252 | }
253 |
254 | public void DrawPixel(short x, short y, short symbol, short color)
255 | {
256 | DrawChar(x, y, (char)symbol, color);
257 | }
258 |
259 | public void DrawText(short x, short y, string text, short color)
260 | {
261 | char[] chars = text.ToCharArray();
262 |
263 | for (int i = 0; i < chars.Length; i++)
264 | {
265 | DrawChar((short)(x + i), y, chars[i], color);
266 | }
267 | }
268 |
269 | public void DrawChar(short x, short y, char @char, short color)
270 | {
271 | SetPixel(x, y, new CharInfo() { Attributes = color, UnicodeChar = @char });
272 | }
273 |
274 | public void FillRect(short x, short y, short width, short height, short character, short color)
275 | {
276 | for (int w = 0; w < width; w++)
277 | {
278 | for (int h = 0; h < height; h++)
279 | {
280 | DrawPixel((short)(x + w), (short)(y + h), character, color);
281 | }
282 | }
283 | }
284 |
285 | protected void SetPixel(short x, short y, CharInfo @char)
286 | {
287 | if (x >= 0 && y >= 0 && x < Width && y < Height)
288 | {
289 | buffer[y * Width + x] = @char;
290 | }
291 | }
292 |
293 | public CharInfo GetPixel(short x, short y)
294 | {
295 | x = (short)MathF.Clamp(x, 0, Width);
296 | y = (short)MathF.Clamp(y, 0, Height);
297 | return buffer[y * Width + x];
298 | }
299 |
300 | protected void Apply()
301 | {
302 | WriteConsoleOutput(GetStdHandle(STDOUT), buffer, new COORD(Width, Height), new COORD(0, 0), ref rect);
303 | }
304 |
305 | protected void Clear()
306 | {
307 | CharInfo ch = new CharInfo();
308 |
309 | for (int i = 0; i < buffer.Length; i++)
310 | {
311 | buffer[i] = ch;
312 | }
313 | }
314 |
315 | protected virtual void OnStart()
316 | {
317 |
318 | }
319 | protected virtual void OnUpdate()
320 | {
321 |
322 | }
323 | protected virtual void OnDraw()
324 | {
325 |
326 | }
327 |
328 | [DllImport("kernel32.dll", SetLastError = true)]
329 | static extern bool SetConsoleScreenBufferSize(IntPtr hConsoleOutput, COORD size);
330 |
331 | [DllImport("kernel32.dll", SetLastError = true)]
332 | static extern bool SetConsoleWindowInfo(IntPtr hConsoleOutput, bool bAbsolute, SmallRect rect);
333 |
334 | [DllImport("kernel32.dll",SetLastError =true)]
335 | static extern bool SetConsoleOutputCP(uint CodePageId);
336 |
337 | [DllImport("kernel32.dll", SetLastError = true)]
338 | static extern bool SetConsoleCP(uint CodePageId);
339 |
340 | [DllImport("kernel32.dll", SetLastError = true)]
341 | static extern bool WriteConsoleOutput(IntPtr hConsoleOutput, CharInfo[] buffer, COORD bufferSize, COORD bufferCoord, ref SmallRect region);
342 |
343 | [DllImport("kernel32.dll", SetLastError = true)]
344 | static extern IntPtr GetStdHandle(int handle);
345 |
346 | [DllImport("kernel32.dll")]
347 | static extern uint GetLastError();
348 |
349 | [DllImport("kernel32.dll", SetLastError = true)]
350 | public static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO buffer);
351 |
352 | [DllImport("kernel32.dll", SetLastError = true)]
353 | static extern int SetCurrentConsoleFontEx(IntPtr ConsoleOutput,bool MaximumWindow, ref CONSOLE_FONT_INFO_EX ConsoleCurrentFontEx);
354 |
355 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
356 | extern static bool GetCurrentConsoleFontEx(IntPtr hConsoleOutput,bool bMaximumWindow,ref CONSOLE_FONT_INFOEX info);
357 |
358 |
359 | }
360 | }
361 |
--------------------------------------------------------------------------------
/Core/ColorUtilites.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 |
4 | namespace MaximovInk.ConsoleGameEngine
5 | {
6 | public static class ColorUtilites
7 | {
8 | public static COLOR GetConsoleColor16(this Color color)
9 | {
10 | if (color.GetSaturation() < 0.5)
11 | {
12 |
13 | float satur = color.GetBrightness() * 3.5f;
14 |
15 | if (satur == 0)
16 | {
17 | return COLOR.FG_BLACK;
18 | }
19 |
20 | }
21 | int hue = (int)Math.Round(color.GetHue() / 60, MidpointRounding.AwayFromZero);
22 | if (color.GetBrightness() < 0.4)
23 | {
24 | switch (hue)
25 | {
26 | case 1: return COLOR.FG_DARK_YELLOW;
27 | case 2: return COLOR.FG_DARK_GREEN;
28 | case 3: return COLOR.FG_DARK_CYAN;
29 | case 4: return COLOR.FG_DARK_BLUE;
30 | case 5: return COLOR.FG_DARK_MAGENTA;
31 | default: return COLOR.FG_DARK_RED;
32 | }
33 | }
34 | switch (hue)
35 | {
36 | case 1: return COLOR.FG_YELLOW;
37 | case 2: return COLOR.FG_GREEN;
38 | case 3: return COLOR.FG_CYAN;
39 | case 4: return COLOR.FG_BLUE;
40 | case 5: return COLOR.FG_MAGENTA;
41 | default: return COLOR.FG_RED;
42 | }
43 | }
44 |
45 | public static void GetConsoleColor(this Color color, out Character ch, out COLOR cl)
46 | {
47 | ch = Character.Null;
48 | cl = COLOR.BG_BLACK;
49 |
50 | float satur = color.GetSaturation();
51 | float light = color.GetBrightness();
52 | float hue = color.GetHue();
53 |
54 | if (satur < 0.1f | light > 0.8f)
55 | {
56 | ch = Character.Full;
57 | cl = COLOR.BG_BLACK;
58 |
59 | ch = light < 0.2 ? Character.Light : light < 0.5 ? Character.Medium : light < 0.8 ? Character.Dark : Character.Full;
60 |
61 | if (light == 0)
62 | {
63 | cl = COLOR.FG_BLACK | COLOR.BG_BLACK;
64 | ch = Character.Medium;
65 | }
66 | else if (light <= 0.1)
67 | {
68 | cl = COLOR.FG_DARK_GREY | COLOR.BG_BLACK;
69 | ch = Character.Medium;
70 | }
71 | else if (light <= 0.3)
72 | {
73 | cl = COLOR.FG_DARK_GREY;
74 | ch = Character.Full;
75 | }
76 | else if (light <= 0.5)
77 | {
78 | cl = COLOR.FG_DARK_GREY | COLOR.BG_GREY;
79 | ch = Character.Medium;
80 | }
81 | else if (light <= 0.6)
82 | {
83 | cl = COLOR.FG_GREY;
84 | ch = Character.Full;
85 | }
86 | else if (light <= 0.8)
87 | {
88 | cl = COLOR.FG_GREY | COLOR.BG_WHITE;
89 | ch = Character.Medium;
90 | }
91 | else
92 | {
93 | cl = COLOR.FG_WHITE;
94 | ch = Character.Full;
95 | }
96 | }
97 | else
98 | {
99 | if (hue <= 10)
100 | {
101 | if (light <= 0.4)
102 | {
103 | cl = COLOR.FG_DARK_RED;
104 | ch = Character.Dark;
105 | }
106 | else if (light <= 0.5)
107 | {
108 | cl = COLOR.FG_RED;
109 | ch = Character.Dark;
110 | }
111 | else if (light <= 0.7)
112 | {
113 | cl = COLOR.FG_RED | COLOR.BG_WHITE;
114 | ch = Character.Medium;
115 | }
116 | else
117 | {
118 | cl = COLOR.FG_RED | COLOR.BG_WHITE;
119 | ch = Character.Light;
120 | }
121 | }
122 | else if (hue <= 30)
123 | {
124 | if (light <= 0.3)
125 | {
126 | cl = COLOR.FG_DARK_RED | COLOR.BG_YELLOW;
127 | ch = Character.Dark;
128 | }
129 | else if (light <= 0.4)
130 | {
131 | cl = COLOR.FG_DARK_RED | COLOR.BG_YELLOW;
132 | ch = Character.Medium;
133 | }
134 | else if (light <= 0.5)
135 | {
136 | cl = COLOR.FG_RED | COLOR.BG_YELLOW;
137 | ch = Character.Medium;
138 | }
139 | else if (light <= 0.7)
140 | {
141 | cl = COLOR.FG_RED | COLOR.BG_WHITE;
142 | ch = Character.Medium;
143 | }
144 | else
145 | {
146 | cl = COLOR.FG_RED | COLOR.BG_WHITE;
147 | ch = Character.Light;
148 | }
149 | }
150 | else if (hue <= 45)
151 | {
152 | if (light <= 0.3)
153 | {
154 | cl = COLOR.FG_YELLOW | COLOR.BG_DARK_RED;
155 | ch = Character.Dark;
156 | }
157 | else if (light <= 0.6)
158 | {
159 | cl = COLOR.FG_YELLOW | COLOR.BG_RED;
160 | ch = Character.Medium;
161 | }
162 | else if (light <= 0.7)
163 | {
164 | cl = COLOR.FG_YELLOW | COLOR.BG_RED;
165 | ch = Character.Light;
166 | }
167 | else
168 | {
169 | cl = COLOR.FG_YELLOW | COLOR.BG_RED;
170 | ch = Character.Light;
171 | }
172 | }
173 | else if (hue <= 65)
174 | {
175 | if (light <= 0.4)
176 | {
177 | cl = COLOR.FG_DARK_YELLOW;
178 | ch = Character.Dark;
179 | }
180 | else if (light <= 0.5)
181 | {
182 | cl = COLOR.FG_YELLOW;
183 | ch = Character.Dark;
184 | }
185 | else if (light <= 0.6)
186 | {
187 | cl = COLOR.FG_YELLOW | COLOR.BG_YELLOW;
188 | ch = Character.Light;
189 | }
190 | else
191 | {
192 | cl = COLOR.FG_YELLOW | COLOR.BG_WHITE;
193 | ch = Character.Light;
194 | }
195 | }
196 | else if (hue <= 96)
197 | {
198 | if (light <= 0.3)
199 | {
200 | cl = COLOR.FG_DARK_GREEN | COLOR.BG_DARK_YELLOW;
201 | ch = Character.Dark;
202 | }
203 | else if (light <= 0.5)
204 | {
205 | cl = COLOR.FG_DARK_GREEN | COLOR.BG_DARK_YELLOW;
206 | ch = Character.Medium;
207 | }
208 | else if (light <= 0.6)
209 | {
210 | cl = COLOR.FG_GREEN | COLOR.BG_YELLOW;
211 | ch = Character.Medium;
212 | }
213 | else if (light <= 0.7)
214 | {
215 | cl = COLOR.FG_GREEN | COLOR.BG_YELLOW;
216 | ch = Character.Light;
217 | }
218 | else
219 | {
220 | cl = COLOR.FG_GREEN | COLOR.BG_WHITE;
221 | ch = Character.Light;
222 | }
223 | }
224 | else if (hue <= 150)
225 | {
226 | if (light <= 0.3)
227 | {
228 | cl = COLOR.FG_DARK_GREEN;
229 | ch = Character.Dark;
230 | }
231 | else if (light <= 0.5)
232 | {
233 | cl = COLOR.FG_DARK_GREEN;
234 | ch = Character.Dark;
235 | }
236 | else if (light <= 0.7)
237 | {
238 | cl = COLOR.FG_GREEN;
239 | ch = Character.Dark;
240 | }
241 | else
242 | {
243 | cl = COLOR.FG_GREEN | COLOR.BG_WHITE;
244 | ch = Character.Light;
245 | }
246 | }
247 | else if (hue <= 150)
248 | {
249 | if (light <= 0.3)
250 | {
251 | cl = COLOR.FG_DARK_CYAN | COLOR.BG_DARK_GREEN;
252 | ch = Character.Dark;
253 | }
254 | else if (light <= 0.5)
255 | {
256 | cl = COLOR.FG_DARK_CYAN | COLOR.BG_DARK_GREEN;
257 | ch = Character.Medium;
258 | }
259 | else if (light <= 0.6)
260 | {
261 | cl = COLOR.FG_CYAN | COLOR.BG_GREEN;
262 | ch = Character.Medium;
263 | }
264 | else if (light <= 0.7)
265 | {
266 | cl = COLOR.FG_CYAN | COLOR.BG_GREEN;
267 | ch = Character.Light;
268 | }
269 | else
270 | {
271 | cl = COLOR.FG_CYAN | COLOR.BG_WHITE;
272 | ch = Character.Light;
273 | }
274 | }
275 | else if (hue <= 190)
276 | {
277 | if (light <= 0.3)
278 | {
279 | cl = COLOR.FG_DARK_CYAN;
280 | ch = Character.Dark;
281 | }
282 | else if (light <= 0.5)
283 | {
284 | cl = COLOR.FG_DARK_CYAN;
285 | ch = Character.Dark;
286 | }
287 | else if (light <= 0.7)
288 | {
289 | cl = COLOR.FG_CYAN;
290 | ch = Character.Dark;
291 | }
292 | else
293 | {
294 | cl = COLOR.FG_CYAN | COLOR.BG_WHITE;
295 | ch = Character.Light;
296 | }
297 | }
298 | else if (hue <= 220)
299 | {
300 | if (light <= 0.3)
301 | {
302 | cl = COLOR.FG_DARK_CYAN | COLOR.BG_DARK_BLUE;
303 | ch = Character.Dark;
304 | }
305 | else if (light <= 0.5)
306 | {
307 | cl = COLOR.FG_DARK_CYAN | COLOR.BG_DARK_BLUE;
308 | ch = Character.Medium;
309 | }
310 | else if (light <= 0.7)
311 | {
312 | cl = COLOR.FG_CYAN | COLOR.BG_BLUE;
313 | ch = Character.Medium;
314 | }
315 | else
316 | {
317 | cl = COLOR.FG_CYAN | COLOR.BG_WHITE;
318 | ch = Character.Light;
319 | }
320 | }
321 | else if (hue <= 240)
322 | {
323 | if (light <= 0.3)
324 | {
325 | cl = COLOR.FG_DARK_BLUE;
326 | ch = Character.Dark;
327 | }
328 | else if (light <= 0.5)
329 | {
330 | cl = COLOR.FG_DARK_BLUE;
331 | ch = Character.Dark;
332 | }
333 | else if (light <= 0.7)
334 | {
335 | cl = COLOR.FG_BLUE;
336 | ch = Character.Dark;
337 | }
338 | else
339 | {
340 | cl = COLOR.FG_BLUE | COLOR.BG_WHITE;
341 | ch = Character.Light;
342 | }
343 | }
344 | else if (hue <= 275)
345 | {
346 | if (light <= 0.3)
347 | {
348 | cl = COLOR.FG_DARK_BLUE | COLOR.BG_DARK_MAGENTA;
349 | ch = Character.Dark;
350 | }
351 | else if (light <= 0.5)
352 | {
353 | cl = COLOR.FG_DARK_BLUE | COLOR.BG_DARK_MAGENTA;
354 | ch = Character.Medium;
355 | }
356 | else if (light <= 0.6)
357 | {
358 | cl = COLOR.FG_BLUE | COLOR.BG_MAGENTA;
359 | ch = Character.Medium;
360 | }
361 | else if (light <= 0.7)
362 | {
363 | cl = COLOR.FG_BLUE | COLOR.BG_MAGENTA;
364 | ch = Character.Light;
365 | }
366 | else
367 | {
368 | cl = COLOR.FG_BLUE | COLOR.BG_WHITE;
369 | ch = Character.Light;
370 | }
371 | }
372 | else if (hue <= 320)
373 | {
374 | if (light <= 0.3)
375 | {
376 | cl = COLOR.FG_DARK_MAGENTA;
377 | ch = Character.Dark;
378 | }
379 | else if (light <= 0.5)
380 | {
381 | cl = COLOR.FG_DARK_MAGENTA;
382 | ch = Character.Dark;
383 | }
384 | else if (light <= 0.7)
385 | {
386 | cl = COLOR.FG_MAGENTA;
387 | ch = Character.Dark;
388 | }
389 | else
390 | {
391 | cl = COLOR.FG_MAGENTA | COLOR.BG_WHITE;
392 | ch = Character.Light;
393 | }
394 | }
395 | else
396 | {
397 | if (light <= 0.3)
398 | {
399 | cl = COLOR.FG_DARK_MAGENTA | COLOR.BG_DARK_RED;
400 | ch = Character.Dark;
401 | }
402 | else if (light <= 0.5)
403 | {
404 | cl = COLOR.FG_DARK_MAGENTA | COLOR.BG_DARK_RED;
405 | ch = Character.Medium;
406 | }
407 | else if (light <= 0.6)
408 | {
409 | cl = COLOR.FG_MAGENTA | COLOR.BG_RED;
410 | ch = Character.Medium;
411 | }
412 | else if (light <= 0.7)
413 | {
414 | cl = COLOR.FG_MAGENTA | COLOR.BG_RED;
415 | ch = Character.Light;
416 | }
417 | else
418 | {
419 | cl = COLOR.FG_MAGENTA | COLOR.BG_WHITE;
420 | ch = Character.Light;
421 | }
422 | }
423 |
424 | }
425 |
426 | }
427 |
428 | public static Color GetRGB(this COLOR color)
429 | {
430 | switch (color)
431 | {
432 | case COLOR.FG_DARK_BLUE:
433 | return Color.FromArgb(0, 0, 128);
434 | case COLOR.FG_DARK_GREEN:
435 | return Color.FromArgb(0, 128, 0);
436 | case COLOR.FG_DARK_CYAN:
437 | return Color.FromArgb(0, 128, 128);
438 | case COLOR.FG_DARK_RED:
439 | return Color.FromArgb(128, 0, 0);
440 | case COLOR.FG_DARK_MAGENTA:
441 | return Color.FromArgb(128, 0, 128);
442 | case COLOR.FG_DARK_YELLOW:
443 | return Color.FromArgb(128, 128, 0);
444 | case COLOR.FG_GREY:
445 | return Color.FromArgb(128, 128, 128);
446 | case COLOR.FG_DARK_GREY:
447 | return Color.FromArgb(192, 192, 192);
448 | case COLOR.FG_BLUE:
449 | return Color.FromArgb(0, 0, 255);
450 | case COLOR.FG_GREEN:
451 | return Color.FromArgb(0, 255, 0);
452 | case COLOR.FG_CYAN:
453 | return Color.FromArgb(0, 255, 255);
454 | case COLOR.FG_RED:
455 | return Color.FromArgb(255, 0, 0);
456 | case COLOR.FG_MAGENTA:
457 | return Color.FromArgb(255, 0,255);
458 | case COLOR.FG_YELLOW:
459 | return Color.FromArgb(255, 255, 0);
460 | case COLOR.FG_WHITE:
461 | return Color.FromArgb(255, 255, 255);
462 | default:
463 | return Color.FromArgb(0, 0, 0);
464 | }
465 | }
466 |
467 | public static COLOR InvertFBG(COLOR color)
468 | {
469 | switch (color)
470 | {
471 | case COLOR.FG_BLACK:
472 | return COLOR.BG_BLACK;
473 | case COLOR.FG_DARK_BLUE:
474 | return COLOR.BG_DARK_GREEN;
475 | case COLOR.FG_DARK_GREEN:
476 | return COLOR.BG_DARK_GREEN;
477 | case COLOR.FG_DARK_CYAN:
478 | return COLOR.BG_DARK_CYAN;
479 | case COLOR.FG_DARK_RED:
480 | return COLOR.BG_DARK_RED;
481 | case COLOR.FG_DARK_MAGENTA:
482 | return COLOR.BG_DARK_MAGENTA;
483 | case COLOR.FG_DARK_YELLOW:
484 | return COLOR.BG_DARK_YELLOW;
485 | case COLOR.FG_GREY:
486 | return COLOR.BG_GREY;
487 | case COLOR.FG_DARK_GREY:
488 | return COLOR.BG_DARK_GREY;
489 | case COLOR.FG_BLUE:
490 | return COLOR.BG_BLUE;
491 | case COLOR.FG_GREEN:
492 | return COLOR.BG_GREEN;
493 | case COLOR.FG_CYAN:
494 | return COLOR.BG_CYAN;
495 | case COLOR.FG_RED:
496 | return COLOR.BG_RED;
497 | case COLOR.FG_MAGENTA:
498 | return COLOR.BG_MAGENTA;
499 | case COLOR.FG_YELLOW:
500 | return COLOR.BG_YELLOW;
501 | case COLOR.FG_WHITE:
502 | return COLOR.BG_WHITE;
503 | case COLOR.BG_DARK_BLUE:
504 | return COLOR.FG_DARK_BLUE;
505 | case COLOR.BG_DARK_GREEN:
506 | return COLOR.FG_DARK_GREEN;
507 | case COLOR.BG_DARK_CYAN:
508 | return COLOR.FG_DARK_CYAN;
509 | case COLOR.BG_DARK_RED:
510 | return COLOR.FG_DARK_RED;
511 | case COLOR.BG_DARK_MAGENTA:
512 | return COLOR.FG_DARK_MAGENTA;
513 | case COLOR.BG_DARK_YELLOW:
514 | return COLOR.FG_DARK_YELLOW;
515 | case COLOR.BG_GREY:
516 | return COLOR.FG_GREY;
517 | case COLOR.BG_DARK_GREY:
518 | return COLOR.FG_DARK_GREY;
519 | case COLOR.BG_BLUE:
520 | return COLOR.FG_BLUE;
521 | case COLOR.BG_GREEN:
522 | return COLOR.FG_GREEN;
523 | case COLOR.BG_CYAN:
524 | return COLOR.FG_CYAN;
525 | case COLOR.BG_RED:
526 | return COLOR.FG_RED;
527 | case COLOR.BG_MAGENTA:
528 | return COLOR.BG_MAGENTA;
529 | case COLOR.BG_YELLOW:
530 | return COLOR.FG_YELLOW;
531 | case COLOR.BG_WHITE:
532 | return COLOR.FG_WHITE;
533 | default:
534 | return COLOR.FG_BLACK;
535 | }
536 | }
537 |
538 | public static void CombineTwoColors(COLOR one, COLOR two, float mix, out Character ch, out COLOR cl)
539 | {
540 | ch = Character.Null;
541 | cl = COLOR.BG_BLACK;
542 |
543 | if (mix < 0.05f)
544 | {
545 | //full
546 | ch = Character.Full;
547 | cl = one | InvertFBG(two);
548 | }
549 | else if (mix < 0.4f)
550 | {
551 | //dark
552 | ch = Character.Dark;
553 | cl = one | InvertFBG(two);
554 | }
555 | else if (mix < 0.6f)
556 | {
557 | //medium
558 | ch = Character.Medium;
559 | cl = one | InvertFBG(two);
560 | }
561 | else if (mix <= 0.95f)
562 | {
563 | //dark
564 | ch = Character.Dark;
565 | cl = two | InvertFBG(one);
566 | }
567 | else
568 | {
569 | //full
570 | ch = Character.Full;
571 | cl = two | InvertFBG(one);
572 | }
573 | }
574 | }
575 | }
576 |
--------------------------------------------------------------------------------