summaryrefslogtreecommitdiff
path: root/src/ansi_terminal.adb
diff options
context:
space:
mode:
authorJedidiah Barber <contact@jedbarber.id.au>2022-11-18 02:40:52 +1300
committerJedidiah Barber <contact@jedbarber.id.au>2022-11-18 02:40:52 +1300
commite7892f0f87a9258d3b45e9d0cf674ce142f761eb (patch)
tree2948e299f1c230bbbf1438d50d186441ba41dc34 /src/ansi_terminal.adb
parente60b21609c013661638191b1251d6ae31c389cf9 (diff)
Refactored code into appropriate packages
Diffstat (limited to 'src/ansi_terminal.adb')
-rw-r--r--src/ansi_terminal.adb123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/ansi_terminal.adb b/src/ansi_terminal.adb
new file mode 100644
index 0000000..c356c21
--- /dev/null
+++ b/src/ansi_terminal.adb
@@ -0,0 +1,123 @@
+
+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 : Natural := Integer (Quantity'Ceiling (Input (X, Y).Density / 4.0));
+ Bit_Index : 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;
+