From e7892f0f87a9258d3b45e9d0cf674ce142f761eb Mon Sep 17 00:00:00 2001 From: Jedidiah Barber Date: Fri, 18 Nov 2022 02:40:52 +1300 Subject: Refactored code into appropriate packages --- src/ansi_terminal.adb | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/ansi_terminal.adb (limited to 'src/ansi_terminal.adb') 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; + -- cgit