1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
-- Programmed by Jedidiah Barber
-- Licensed under the Sunset License v1.0
-- See license.txt for further details
with
Ada.Characters.Latin_1,
Ada.Strings.Fixed,
Ada.Text_IO;
package body ANSI_Terminal is
package Latin renames Ada.Characters.Latin_1;
package IO renames Ada.Text_IO;
function Clear_Screen
return String is
begin
-- ANSI control sequence Erase in Display
-- Variant to clear entire screen
return Latin.ESC & "[2J";
end Clear_Screen;
function Reset_Cursor
return String is
begin
-- ANSI control sequence Cursor Position
-- Parameters to move cursor to top left corner
return Latin.ESC & "[1;1H";
end Reset_Cursor;
procedure Clear_Screen is
begin
IO.Put (Clear_Screen);
end Clear_Screen;
procedure Reset_Cursor is
begin
IO.Put (Reset_Cursor);
end Reset_Cursor;
function BG_Color_Code
(Value : in Natural)
return String
is
use Ada.Strings;
use Ada.Strings.Fixed;
begin
-- ANSI sequence to change text background colour
-- Total length is always 11 characters
-- It doesn't have to be, but the consistency is important for rendering
return Latin.ESC & "[48;5;" & Tail (Trim (Integer'Image (Value), Left), 3, '0') & "m";
end BG_Color_Code;
function Lookup
(Input : in March_Cell_Grid;
X, Y : in Integer)
return String
is
Average_Density : constant Natural :=
Integer (Quantity'Ceiling (Input (X, Y).Density / 4.0));
Bit_Index : constant Positive :=
Integer (Input (X, Y).Index) + 1;
Choice : Natural;
begin
case Average_Density is
when 1 .. 2 => Choice := 19; -- dark blue
when 3 .. 4 => Choice := 20; -- slightly less dark blue
when 5 .. 6 => Choice := 21; -- slightly dark blue
when 7 .. 8 => Choice := 12; -- blue
when 9 .. 10 => Choice := 14; -- cyan
when 11 .. 12 => Choice := 10; -- green
when 13 .. 14 => Choice := 11; -- yellow
when 15 .. 16 => Choice := 3; -- dark yellow
when 17 .. 18 => Choice := 9; -- red
when 19 .. 20 => Choice := 1; -- dark red
when others => Choice := 0; -- black
end case;
-- Total length should always be 12 characters
return BG_Color_Code (Choice) & Liquid_Chars (Bit_Index);
end Lookup;
function Marching_Squares
(Input : in Particle_Vector)
return String
is
-- Having the grid be one bigger around the edges simplifies calculations
Grid : March_Cell_Grid (0 .. 81, 0 .. 26);
-- 80 cols * 25 rows * 12 chars/cell + 24 linefeeds + 4 char color reset = 24028
-- Oh yeah, baby, big strings
Output : String (1 .. 24028);
X, Y, S : Integer;
begin
for P of Input loop
X := Integer (Plane.Re (P.Place) - 0.5);
Y := Integer (Plane.Im (P.Place) / 2.0 - 0.5);
if X >= 0 and X <= 80 and Y >= 0 and Y <= 25 then
for J in Integer range 0 .. 1 loop
for I in Integer range 0 .. 1 loop
Grid (X + I, Y + J).Index :=
Grid (X + I, Y + J).Index or (2 ** (I + 2 * J));
Grid (X + I, Y + J).Density :=
Grid (X + I, Y + J).Density + P.Density;
end loop;
end loop;
end if;
end loop;
for J in Integer range 1 .. 25 loop
for I in Integer range 1 .. 80 loop
S := (J - 1) * 961 + (I - 1) * 12 + 1;
Output (S .. S + 11) := Lookup (Grid, I, J);
end loop;
Output (J * 961) := Latin.LF;
end loop;
Output (24025 .. 24028) := Latin.ESC & "[0m";
return Output;
end Marching_Squares;
end ANSI_Terminal;
|