home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / tools / wmgs.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  297.1 KB  |  8,964 lines

  1. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. --menudraw.sp
  3. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4. package MENU_DRAW is
  5.  
  6.   type NESTED_LEVEL is ( ONE, TWO, THREE, FOUR );
  7.  
  8.   procedure DRAW_ERROR_PORT ( TEXT1 : in string; TEXT : in string );
  9.  
  10.   procedure DRAW_DP_MENU ( LEVEL : in NESTED_LEVEL );
  11.  
  12.   procedure DRAW_SDF_MENU ( CMD_DRAW : in boolean := true );
  13.  
  14.   procedure DRAW_DIG_MENU;
  15.  
  16.   procedure DRAW_PLC_MENU;
  17.  
  18.   procedure DRAW_SESSION_MENU;
  19.  
  20.   procedure DRAW_MAP_MENU;
  21.  
  22. --  procedure DRAW_HELP_MENU;
  23.  
  24. --  procedure DRAW_HELP_SUB_MENU;
  25.  
  26.   procedure INITIALIZE_MENUS;
  27.  
  28.   procedure DRAW_PROJ_PARAM_FIELDS ( OMIT : in boolean := false );
  29.  
  30.   procedure DRAW_PROJ_LIMIT_FIELDS ( OMIT : in boolean := false );
  31.  
  32.   procedure DRAW_SESSION_FILENAME;
  33.   procedure DRAW_DISPLAY_FILENAME;
  34.  
  35. end MENU_DRAW;
  36. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  37. --menuparse.sp
  38. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  39. package MENU_PARSE is
  40.  
  41.   type MENUS is ( SESSION, DISPLAY_PARAM, SEC_DISPLAY_PARAM,
  42.                -- HELP_TOPIC,
  43.                -- HELP_SUBTOPIC, 
  44.                   SPECIAL_DISPLAY, DIAGNOSTIC, MAP_OF, PLOTTER_CHAR );
  45.  
  46.   type COMMAND is ( EDIT, CONTINUE, SAVE, 
  47.                  -- HELP, 
  48.                     LEAVE, QUIT, 
  49.                  -- UNDO, 
  50.                     SPECIAL, 
  51.                  -- APPEND, 
  52.                     OPENF );
  53.  
  54.   procedure INITIALIZE_PARSE;
  55.  
  56.   function PARSE_COMMAND_LINE return COMMAND;
  57.   function CURRENT_MENU       return MENUS;
  58.  
  59.   procedure EDIT;
  60.   procedure CONTINUE;
  61.   procedure SAVE;
  62. --  procedure HELP;
  63.   procedure LEAVE;
  64.   procedure QUIT;
  65. --  procedure UNDO;
  66.   procedure SPECIAL;
  67. --  procedure APPEND;
  68.   procedure OPENF;
  69.  
  70. end MENU_PARSE;
  71. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  72. --menufilei.sp
  73. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  74. package MENU_FILE_IO is
  75.  
  76.   procedure OPEN_MENU_FILE   ( FILE : in string ); -- use for OPENF command.
  77.   procedure CREATE_MENU_FILE ( FILE : in string ); -- use for SAVE command.
  78.   procedure CLOSE_MENU_FILE; -- use for OPENF & SAVE commands.
  79.  
  80.   procedure WRITE_DISPLAY_CURRENTS;
  81.   procedure WRITE_SESSION_CURRENTS;
  82.   procedure READ_DISPLAY_DEFAULTS;
  83.   procedure READ_SESSION_DEFAULTS;
  84.  
  85. end MENU_FILE_IO;
  86. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  87. --worlddata.sp
  88. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  89. with DIRECT_IO;
  90. package WORLD_DATA_FILES is
  91.  
  92. -- type LATITUDE_LONGITUDE_PAIR is 
  93. --   record
  94. --     LATITUDE      :      float;
  95. --     LONGITUDE     :      float;
  96. --   end record;
  97.  
  98. --  MAXIMUM_LAT_LON_PAIRS      :      constant integer := 750;
  99.  
  100.   MAXIMUM_LAT_LON_PAIRS      :      constant integer := 1000;
  101.  
  102.   subtype LAT_LON_PAIR_INDEX is integer range 1 .. MAXIMUM_LAT_LON_PAIRS;
  103.  
  104.   type SET_OF_LAT_LON_PAIRS is array (LAT_LON_PAIR_INDEX'first .. 
  105.        LAT_LON_PAIR_INDEX'last) of float;
  106.  
  107.   type LAT_LON_RECORD is
  108.     record
  109.       NUMBER_OF_PAIRS      :      LAT_LON_PAIR_INDEX;
  110.       MINIMUM_LAT          :      float;
  111.       MAXIMUM_LAT          :      float;
  112.       MINIMUM_LON          :      float;
  113.       MAXIMUM_LON          :      float;
  114.       LAT_LON_PAIRS        :      SET_OF_LAT_LON_PAIRS;
  115.     end record;
  116.  
  117.   package WORLD_DATA_IO is new DIRECT_IO ( LAT_LON_RECORD );
  118.  
  119. end WORLD_DATA_FILES;
  120. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  121. --graphic.sp
  122. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  123. package Graphic is
  124.  
  125.   type    View_Port is private;
  126.   subtype Coordinate is float;
  127.   type    Color_Type is (Black, Brown, Blue, Green, Yellow, Red, White);
  128.   subtype Color_Spectrum is float;   -- range is 0.0 .. 1.0
  129.   type    Terminal_Mode is (Graphics, Text);
  130.  
  131.   procedure Create_Port(Port : in out View_Port;
  132.                         Left, Top, Width, Height : in Coordinate);
  133.   procedure Create_Port(Port : in out View_Port;
  134.                         Left, Top, Width, Height : in integer);
  135.   procedure Redefine(Port: in out View_Port;
  136.                      Left, Top, Width, Height: in Coordinate);
  137.   procedure Redefine(Port: in out View_Port;
  138.                      Left, Top, Width, Height: in integer);
  139.   procedure New_Screen_Size(Columns, Lines : in integer);
  140.   procedure Set_Window(Left, Bottom, Right, Top  : in Coordinate);
  141.   procedure Set_Window(Left, Bottom, Right, Top  : in integer);
  142.   procedure Select_Port(Port: in View_Port);
  143.   procedure Erase_Screen;
  144.   procedure Erase_Port(Color : in Color_Type);
  145.   procedure Erase_Port(Color : in Color_Spectrum := 0.0);
  146.   procedure Erase_Port(Port: in View_Port; Color : in Color_Type);
  147.   procedure Erase_Port(Port: in View_Port; Color : in Color_Spectrum := 0.0);
  148.   procedure Frame_Port;
  149.   procedure Move_To(New_X, New_Y  : in Coordinate);
  150.   procedure Move_To(New_X, New_Y  : in integer);
  151.   procedure Move(Delta_X, Delta_Y : in Coordinate);
  152.   procedure Move(Delta_X, Delta_Y : in integer);
  153.   procedure Clip(X1, Y1, X2, Y2 : in out Coordinate; In_View : in out boolean);
  154.   procedure Draw_Line(Start_WX, Start_WY, End_WX, End_WY : in Coordinate;
  155.                       Color : in Color_Spectrum);
  156.   procedure Line_To(New_X, New_Y  : in Coordinate);
  157.   procedure Line_To(New_X, New_Y  : in integer);
  158.   procedure Line(Delta_X, Delta_Y : in Coordinate);
  159.   procedure Line(Delta_X, Delta_Y : in integer);
  160.   function  Set_Color(Color_Code  : in Color_Spectrum) return Color_Spectrum;
  161.   function  Set_Color(Color : in Color_Type) return Color_Type;
  162.   procedure Set_Color(Color_Code : in Color_Spectrum);
  163.   procedure Set_Color(Color : in Color_Type);
  164.   procedure Where_Am_I(Current_X, Current_Y : out Coordinate);
  165.   procedure Set_Mode(Mode : in Terminal_Mode);
  166.   procedure Print_Screen(File_Name : String);
  167.   function  What_Port return View_Port;
  168.  
  169.   Illegal_Color       : exception;  -- Set color outside 0.0 .. 1.0
  170.   Illegal_Screen_Size : exception;  -- Screen size unavailable for this terminal
  171.   Not_Implemented     : exception;
  172.   Terminal_Limitation : exception;
  173.   Undefined_Window    : exception;  -- Attempt to draw without a defined window
  174.   Value_Off_Screen    : exception;  -- Veiw_Port boundaries
  175.   Zero_Area           : exception;  -- Window boundaries
  176.  
  177. private
  178.  
  179.   subtype Pixel is integer;
  180.   type V_Port is record
  181.          Color : Color_Spectrum;            -- current color
  182.          Window_Defined : boolean;          -- true iff Set_Window called
  183.          X_Current, Y_Current : Coordinate; -- last point drawn or moved to
  184.          X_Scale, Y_Scale : float;          -- scale factor to pixel coordinates
  185.          X_Shift, Y_Shift : float;          -- shift factor from screen origin
  186.          Left,    Right,
  187.          Top,     Bottom : Pixel;           -- view_port pixel boundaries
  188.          WX_Min,  WX_Max,
  189.          WY_Min,  WY_Max : Coordinate;      -- view_port world boundaries
  190.        end record;  
  191.   type View_Port is access V_Port;
  192.  
  193. end Graphic;
  194. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  195. --termfunct.sp
  196. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  197. --
  198. --  TERM_FUNCTIONS will define a series of functions and procedures which 
  199. -- allow simple cursor positioning and I/O to a graphics terminal in text mode.  
  200. -- Any terminal which supports ASCII standards will work.  Any terminal dependent 
  201. -- features are outlined as such, and would need to be modified for a particular 
  202. -- terminal.
  203. --
  204. package TERM_FUNCTIONS is
  205.  
  206.   subtype POSITIVE_NUMBER is integer range 0 .. integer'last;
  207.  
  208.   type CURSOR_HALF is ( TOP, BOTTOM );
  209.  
  210.   type TERMINAL_STATUS is ( READY, ERROR_RESET_RETRY );
  211.  
  212.   type CURSOR_POS is
  213.     record
  214.       LINE      :      POSITIVE_NUMBER;
  215.       COLUMN    :      POSITIVE_NUMBER;
  216.     end record;
  217.  
  218.   type DEVICE_TYPE is ( VT52, VT100, VT102, VT240 );
  219.  
  220.   type TOKEN is ( UP_ARROW, DOWN_ARROW, RIGHT_ARROW, LEFT_ARROW, RETURN_KEY,
  221.                   BACK_SPACE, TAB, ALPHA_NUM );
  222.  
  223.   procedure SET_TOP_AND_BOTTOM_MARGINS ( TOP, BOTTOM : in POSITIVE_NUMBER );
  224.  
  225.   procedure SET_HOME;
  226.   procedure RESET_HOME;
  227.  
  228.   procedure POSITION_CURSOR ( ITEM              : in  CURSOR_POS );
  229.  
  230.   procedure FILL ( CONSTRAIN : in integer );
  231.   procedure FLUSH ( ITEM : out string; LAST : out integer );
  232.   
  233.   procedure PUT_STRING ( ITEM : in string );
  234.   procedure GET_CHAR   ( ITEM : in out character );
  235. --
  236. --  Convert a floating point number to a string.
  237. --
  238.   function  FL_STRING  ( ITEM : in float ) return string;
  239.   function  STRING_FL  ( ITEM : in string ) return float;
  240. --
  241. --  Interpret keystrokes from the terminal and return the type of token.
  242. --
  243.   function  PARSE_INPUT      return TOKEN;
  244. --
  245. --  Return the last character parsed.
  246. --
  247.   function  PARSED_CHAR      return CHARACTER;
  248.  
  249.   procedure CURSOR_HOME;
  250.  
  251.   procedure SET_132_COLUMNS_PER_LINE; -- VT DEPENDENT.
  252.   procedure SET_80_COLUMNS_PER_LINE;
  253.  
  254.   procedure SET_LOCAL_ECHO;
  255.   procedure RESET_LOCAL_ECHO;
  256.  
  257. end TERM_FUNCTIONS;
  258. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  259. --menutypes.sp
  260. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  261. with GRAPHIC;
  262. package MENU_TYPES is
  263.  
  264.   use GRAPHIC;
  265.  
  266.   subtype FILENAME  is string ( 1 .. 40 );
  267.   subtype MAP_TITLE is string ( 1 .. 40 );
  268.  
  269.   type KIND_OF_PROJECTION is ( STEREOGRAPHIC, ORTHOGRAPHIC, GNOMONIC, SATELLITE,
  270.                  LAMBERT,      AZIMUTHAL,    CARTESIAN,  MERCATOR );
  271.  
  272. --  type PROJECTION_PARAMETERS ( KIND : KIND_OF_PROJECTION := ORTHOGRAPHIC ) is
  273. --    record
  274. --      LAT_CENTER      :      float := 0.0;
  275. --      LON_CENTER      :      float := 0.0;
  276. --      CLK_ROT_AR_CENT :      float := 0.0;
  277. --      case KIND is
  278. --        when SATELLITE =>
  279. --          SAT_ALTITUDE    :      float := 0.0;
  280. --          VIEW_ALTITUDE   :      float := 0.0;
  281. --        when others    =>
  282. --          null;
  283. --      end case;
  284. --    end record;
  285.  
  286.   type PROJECTION_PARAMETERS is
  287.     record
  288.       LAT_CENTER      :      float;
  289.       LON_CENTER      :      float;
  290.       CLK_ROT_AR_CENT :      float;
  291.       SAT_ALTITUDE    :      float;
  292.       VIEW_ALTITUDE   :      float;
  293.     end record;
  294.  
  295.   type GRID_LINE_PARAMETERS is
  296.     record
  297.       SHOW_LINES            :      boolean;
  298.       DEGREES_BTWN_LATS     :      float;
  299.       DEGREES_BTWN_LONS     :      float;
  300.       SEGMENT_LENGTH        :      float;
  301.     end record;
  302.  
  303.   type KIND_OF_PROJECTION_LIMIT is ( ALL_EARTH, MIN_MAX_LAT_LON, 
  304.             MIN_MAX_COORDINATES, ANGULAR_DIST_FROM_PROJECTION_CENTER,
  305.             LAT_LON_BOUNDARY );
  306.  
  307.   type CORRD is 
  308.     record
  309.       X      :      float;
  310.       Y      :      float;
  311.     end record;
  312.  
  313. --  type PROJECTION_LIMITS ( KIND : KIND_OF_PROJECTION_LIMIT := ALL_EARTH ) is
  314. --    record
  315. --      case KIND is
  316. --        when MIN_MAX_LAT_LON =>
  317. --          MIN_LAT_LON           :  CORRD;
  318. --          MAX_LAT_LON           :  CORRD;
  319. --        when MIN_MAX_COORDINATES =>
  320. --          NORTH_EAST            :  CORRD;
  321. --          SOUTH_WEST            :  CORRD;
  322. --        when ANGULAR_DIST_FROM_PROJECTION_CENTER =>
  323. --          ANGLE_UP              :  float;
  324. --          ANGLE_DOWN            :  float;
  325. --          ANGLE_RIGHT           :  float;
  326. --          ANGLE_LEFT            :  float;
  327. --        when LAT_LON_BOUNDARY =>
  328. --          POINT_UP              :  CORRD;
  329. --          POINT_DOWN            :  CORRD;
  330. --          POINT_RIGHT           :  CORRD;
  331. --          POINT_LEFT            :  CORRD;
  332. --        when others =>
  333. --          null;
  334. --      end case;
  335. --    end record;
  336.  
  337.   type PROJECTION_LIMITS is
  338.     record
  339.       MIN_LAT_LON           :  CORRD;
  340.       MAX_LAT_LON           :  CORRD;
  341.       NORTH_EAST            :  CORRD;
  342.       SOUTH_WEST            :  CORRD;
  343.       ANGLE_UP              :  float;
  344.       ANGLE_DOWN            :  float;
  345.       ANGLE_RIGHT           :  float;
  346.       ANGLE_LEFT            :  float;
  347.       POINT_UP              :  CORRD;
  348.       POINT_DOWN            :  CORRD;
  349.       POINT_RIGHT           :  CORRD;
  350.       POINT_LEFT            :  CORRD;
  351.     end record;
  352.  
  353.   type COLOR_SELECTION is
  354.     record
  355.       BACKGROUND            :      COLOR_TYPE;
  356.       DEFAULT               :      COLOR_TYPE;
  357.       MAP_OUTLINE           :      COLOR_TYPE;
  358.       GRID_LINES            :      COLOR_TYPE;
  359.       HORIZON               :      COLOR_TYPE;
  360.     end record;
  361.  
  362.   type SPECIAL_DISPLAYS is
  363.     record
  364.       BEAM_DATA          :      FILENAME  ;
  365.       BEAM_COLOR         :      COLOR_TYPE;
  366.       BEAM_LAST          :      integer;
  367.       SWATH_DATA         :      FILENAME  ;
  368.       SWATH_COLOR        :      COLOR_TYPE;
  369.       SWATH_LAST         :      integer;
  370.       POINTS_DATA        :      FILENAME  ;
  371.       POINTS_COLOR       :      COLOR_TYPE;
  372.       POINTS_LAST        :      integer;
  373.     end record;
  374.  
  375.   type DIAGNOSTICS is
  376.     record
  377.       WARNING            :      boolean;
  378.       ERROR              :      boolean;
  379.       FATAL              :      boolean;
  380.     end record;
  381.  
  382.   type PLOT_CHARACTERISTICS is
  383.     record
  384.       AXIS_LENGTH      :      CORRD;
  385.       ORIGIN           :      CORRD;
  386.     end record;
  387.  
  388. end MENU_TYPES;
  389. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  390. --menutext.sp
  391. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  392. package MENU_TEXT is
  393. --
  394. --                Menu Dimensions
  395. --
  396.    width_max           :      constant integer := 132;
  397.    height_max          :      constant integer := 24;
  398.  
  399.    LEVEL_2_WIDTH       :      constant integer := width_max  - 8;
  400.    LEVEL_2_HEIGHT      :      constant integer := height_max - 6;
  401.    LEVEL_3_WIDTH       :      constant integer := width_max  - 12;
  402.    LEVEL_3_HEIGHT      :      constant integer := height_max - 11;
  403.    LEVEL_4_WIDTH       :      constant integer := width_max  - 16;
  404.    LEVEL_4_HEIGHT      :      constant integer := height_max - 14;
  405.  
  406.    COM_1_INDENT        :      constant integer := 5;
  407.    COM_2_INDENT        :      constant integer := 10;
  408.    COM_3_INDENT        :      constant integer := 15;
  409.    COM_4_INDENT        :      constant integer := 20;
  410.  
  411.    FIELD_1_3_MAX       :      constant integer := 4;
  412.    FIELD_4_MAX         :      constant integer := 6;
  413.    FIELD_5_MAX         :      constant integer := 5;
  414.  
  415. --
  416. --                Menu Text
  417. --
  418.    DP_TITLE_LINE       :      constant string  := "Display Parameters";
  419.    DP_T_LEV_1          :      constant integer := 
  420.                        ( WIDTH_MAX - DP_TITLE_LINE'length ) / 2;
  421.    DP_T_LEV_2          :      constant integer :=
  422.                        ( LEVEL_2_WIDTH - DP_TITLE_LINE'length ) / 2;
  423.  
  424.    SDF_TITLE           :      constant string  := "Special Display Functions";
  425.    SDF_T_LEV_3         :      constant integer := 
  426.                        ( LEVEL_3_WIDTH - SDF_TITLE'length ) / 2;
  427.  
  428.    DIG_TITLE           :      constant string  := "Diagnostic Settings";
  429.    DIG_T_LEV_4         :      constant integer :=
  430.                        ( LEVEL_4_WIDTH - DIG_TITLE'length ) / 2;
  431.  
  432.    PLC_TITLE           :      constant string  := "Plot Characteristics";
  433.    PLC_T_LEV_4         :      constant integer :=
  434.                        ( LEVEL_4_WIDTH - PLC_TITLE'length ) / 2;
  435.  
  436.    SES_TITLE           :      constant string  := "Session Defaults";
  437.    SES_T_LEV_1         :      constant integer :=
  438.                        ( WIDTH_MAX - SES_TITLE'length ) / 2;
  439.  
  440.    MAP_TITLEM          :      string ( 1 .. 47 ) := "Map Of:   " &
  441.                        "          " & "          " & "          "&
  442.                        "       ";
  443.    MAP_T_LEV_1         :      constant integer :=
  444.                        ( WIDTH_MAX - MAP_TITLEM'length ) / 2;
  445.  
  446. --   HTOP_TITLE          :      string ( 1 .. 22 ) := "Help <    " &
  447. --                       "           >";
  448. --   HTOP_LEV_2          :      constant integer :=
  449. --                       ( LEVEL_2_WIDTH - HTOP_TITLE'length ) / 2;
  450. --   HTOP_LEV_3          :      constant integer :=
  451. --                       ( LEVEL_3_WIDTH - HTOP_TITLE'length ) / 2;
  452.  
  453.   C0                   :      constant string := "o Map title:";
  454.   C1                   :      constant string := "o Projection parameters type:";
  455.   C2                   :      constant string := "o Lat of center of projection:";
  456.   C3                   :      constant string := "o Lon of center of projection:";
  457.   C4                   :      constant string := "o Rot clockwise around center:";
  458.   C5                   :      constant string := "o Satellite altitude         :";
  459.   C6                   :      constant string := "o Viewing altitude           :";
  460.   C7                   :      constant string := "o Projection limits type:";
  461.   C8                   :      constant string := "o Minimum longitude:";
  462.   C9                   :      constant string := "o Minimum latitude :";
  463.   C10                  :      constant string := "o Maximum longitude:";
  464.   C11                  :      constant string := "o Maximum latitude :";
  465.   C12                  :      constant string := "o North East X     :";
  466.   C13                  :      constant string := "o North East Y     :";
  467.   C14                  :      constant string := "o South West X     :";
  468.   C15                  :      constant string := "o South West Y     :";
  469.   C16                  :      constant string := "o Angle Up         :";
  470.   C17                  :      constant string := "o Angle Down       :";
  471.   C18                  :      constant string := "o Angle Right      :";
  472.   C19                  :      constant string := "o Angle Left       :";
  473.   C20                  :      constant string := "o Point Up X       :";
  474.   C21                  :      constant string := "o Point Up Y       :";
  475.   C22                  :      constant string := "o Point Down X     :";
  476.   C23                  :      constant string := "o Point Down Y     :";
  477.   C24                  :      constant string := "o Point Right X    :";
  478.   C25                  :      constant string := "o Point Right Y    :";
  479.   C26                  :      constant string := "o Point Left X     :";
  480.   C27                  :      constant string := "o Point Left Y     :";
  481.   C28                  :      constant string := "o Color selection";
  482.   C29                  :      constant string := "o Map outline:";
  483.   C30                  :      constant string := "o Grid line  :";
  484.   C31                  :      constant string := "o Horizon    :";
  485.   C3A                  :      constant string := "o Default    :";
  486.   C3B                  :      constant string := "o Background :";
  487.   C32                  :      constant string := "o Grid line parameters";
  488.   C33                  :      constant string := "o Show lines                :";
  489.   C34                  :      constant string := "o Degrees between latitudes :";
  490.   C35                  :      constant string := "o Degrees between longitudes:";
  491.   C3C                  :      constant string := "o Segment length degrees    :";
  492. --  C36                  :      constant string := "o Clipping :";
  493.   C37                  :      constant string := "o Beam   data  :";
  494.   C38                  :      constant string := "o Symbol data  :";
  495.   C39                  :      constant string := "o Map    data  :";
  496.   C40                  :      constant string := "o Beam   color :";
  497.   C41                  :      constant string := "o Symbol color :";
  498.   C42                  :      constant string := "o Map    color :";
  499.   C43                  :      constant string := "o Warning:";
  500.   C44                  :      constant string := "o Error  :";
  501.   C45                  :      constant string := "o Fatal  :";
  502.   C46                  :      constant string := "o Axis length X:";
  503.   C47                  :      constant string := "o Axis length Y:";
  504.   C48                  :      constant string := "o Origin      X:";
  505.   C49                  :      constant string := "o Origin      Y:";
  506.   C50                  :      constant string := "o Session menu filename:";
  507.   C51                  :      constant string := "o Display menu filename:";
  508.   C52                  :      constant string := "o Show Land:";
  509. --
  510. --                Command Line Text
  511. --
  512.   CL1                  :      constant string := 
  513.       "Edit      Continue      Save      Exit      Quit      Openf";
  514.   CL2                  :      constant string := 
  515.       "Edit      Continue      Exit      Quit";
  516.   CL3                  :      constant string := 
  517.       "Edit      Save          Continue  Exit      Quit      Openf";
  518.   CL4                  :      constant string := 
  519.       "Edit      Special       Continue  Exit      Quit";
  520.   CL5                  :      constant string := 
  521.       "Continue  Exit          Quit";
  522. --
  523. --                Command Line Field Offsets from start in X direction
  524. --
  525.   
  526.   COM_FIE_OFF          :      constant array ( 1 .. 7 ) of integer :=
  527.                        ( 0, 10, 24, 34, 44, 54, 64 );
  528.  
  529.  
  530. end MENU_TEXT;
  531. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  532. --menucurre.sp
  533. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  534. with MENU_TYPES;
  535. package MENU_CURRENTS is
  536.  
  537.   use MENU_TYPES;
  538.  
  539.   CURRENT_TYPE_OF_PROJECTION            :      KIND_OF_PROJECTION;
  540.   CURRENT_TYPE_OF_PROJECTION_LIMIT      :      KIND_OF_PROJECTION_LIMIT;
  541.  
  542.   CURRENT_MAP_TITLE                     :      MAP_TITLE;
  543.   CURRENT_GRID_LINES                    :      GRID_LINE_PARAMETERS;
  544.   CURRENT_COLOR                         :      COLOR_SELECTION;
  545.   CURRENT_SPECIALS                      :      SPECIAL_DISPLAYS;
  546.  
  547.   CURRENT_PROJECTION                    :      PROJECTION_PARAMETERS;
  548.   CURRENT_PROJECTION_LIM                :      PROJECTION_LIMITS;
  549.  
  550.   CURRENT_PLOT_CHARACTERISTICS          :      PLOT_CHARACTERISTICS;
  551.  
  552.   --CURRENT_CLIPPING                      :      boolean;
  553.   CURRENT_LAND                          :      boolean;
  554.   
  555.   CURRENT_DIAGS                         :      DIAGNOSTICS;
  556.  
  557.   CURRENT_SESSION_FILENAME              :      FILENAME;
  558.   CURRENT_DISPLAY_FILENAME              :      FILENAME;
  559.  
  560.   SESSION_TERMINATED                    :      boolean;
  561.  
  562.   STATUS                                :      DIAGNOSTICS;
  563.   DRAW_MAP                              :      boolean;
  564.  
  565.   DEFAULT_TYPE_OF_PROJECTION            :      KIND_OF_PROJECTION;
  566.   DEFAULT_TYPE_OF_PROJECTION_LIMIT      :      KIND_OF_PROJECTION_LIMIT;
  567.  
  568.   DEFAULT_MAP_TITLE                     :      MAP_TITLE;
  569.   DEFAULT_GRID_LINES                    :      GRID_LINE_PARAMETERS;
  570.   DEFAULT_COLOR                         :      COLOR_SELECTION;
  571.   DEFAULT_SPECIALS                      :      SPECIAL_DISPLAYS;
  572.  
  573.   DEFAULT_PROJECTION                    :      PROJECTION_PARAMETERS;
  574.   DEFAULT_PROJECTION_LIM                :      PROJECTION_LIMITS;
  575.  
  576.   DEFAULT_PLOT_CHARACTERISTICS          :      PLOT_CHARACTERISTICS;
  577.  
  578. --  DEFAULT_CLIPPING                      :      boolean;
  579.   DEFAULT_LAND                          :      boolean;
  580.  
  581.   DEFAULT_DIAGS                         :      DIAGNOSTICS;
  582.  
  583.   procedure SET_CURRENTS_FROM_DEFAULTS;
  584.   procedure SET_DEFAULTS_FROM_CURRENTS;
  585.  
  586. end MENU_CURRENTS;
  587. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  588. --worldmenu.sp
  589. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  590. --*P*
  591. --*P*      The purpose of World_Menu is to provide the values which represent
  592. --*P* the menu fields and indicate the end of the mapping session.  It also 
  593. --*P* provides procedures to initialize the World_Menu capability and the stub 
  594. --*P* which starts the menu generation cycle.
  595. --*P*
  596. with MENU_TYPES;
  597. --*D*
  598. --*D*       Menu_Types provides all the type information for the menu fields.
  599. --*D*
  600. package WORLD_MENUS is
  601.  
  602.   use MENU_TYPES;
  603.  
  604.   function END_OF_SESSION                return boolean;
  605.  
  606.   function TYPE_OF_PROJECTION            return KIND_OF_PROJECTION;
  607.   function TYPE_OF_PROJECTION_LIMIT      return KIND_OF_PROJECTION_LIMIT;
  608.  
  609.   function CURRENT_TITLE                 return MAP_TITLE;
  610.   function CURRENT_PROJECTION_PARAMETERS return PROJECTION_PARAMETERS;
  611.   function CURRENT_PROJECTION_LIMITS     return PROJECTION_LIMITS;
  612.   function CURRENT_GRID_LINE_PARAMETERS  return GRID_LINE_PARAMETERS;
  613.   function CURRENT_COLOR_SELECTION       return COLOR_SELECTION;
  614.   function CURRENT_SPECIAL_DISPLAYS      return SPECIAL_DISPLAYS;
  615.   function CURRENT_DIAGNOSTICS           return DIAGNOSTICS;
  616.   function CURRENT_PLOT_CHAR             return PLOT_CHARACTERISTICS;
  617.  
  618.   function PLOT_LAND                     return boolean;
  619.   function SHOW_GRID                     return boolean;
  620.   function SHOW_BEAM                     return boolean;
  621.   function SHOW_SWATH                    return boolean;
  622. --  function CLIPPING                      return boolean;
  623.  
  624.   procedure GENERATE_MENUS;
  625.   procedure INITIALIZE;
  626.  
  627. end WORLD_MENUS;            
  628. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  629. --menuconst.sp
  630. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  631. with MENU_TEXT, TERM_FUNCTIONS;
  632. package MENU_CONSTANTS is
  633.  
  634.   use MENU_TEXT;
  635.   use TERM_FUNCTIONS;
  636.  
  637.   type FIELD_INDEX is  
  638.        ( CI0,  CI1,  CI2,  CI3,  CI4,  CI5,  CI6,  CI7,  CI8,  CI9,
  639.          CI10, CI11, CI12, CI13, CI14, CI15, CI16, CI17, CI18, CI19,
  640.          CI20, CI21, CI22, CI23, CI24, CI25, CI26, CI27, CI28, CI29,
  641.          CI30, CI31, CI3A, CI3B, 
  642.                      CI32, CI33, CI34, CI35, CI3C,
  643.        --CI36, 
  644.          CI37, CI38, CI39,
  645.          CI40, CI41, CI42, CI43, CI44, CI45, CI46, CI47, CI48, CI49,
  646.          CI50, CI51, CI52 );
  647.   
  648.   X_Y_POS      :      constant array ( FIELD_INDEX'first .. FIELD_INDEX'last )
  649.                                        of TERM_FUNCTIONS.CURSOR_POS :=
  650. -- Display Parameters Title Line. C0
  651.    ( ( LINE => 07, COLUMN => 10 ),
  652.  
  653. -- Display Parameters/Projection Parameters/Projection Type. C1
  654.      ( LINE => 09, COLUMN => 10 ),
  655. -- Display Parameters/Projection Parameters/Lat of center.   C2
  656.      ( LINE => 10, COLUMN => 12 ),
  657. -- Display Parameters/Projection Parameters/Lon of center.   C3
  658.      ( LINE => 11, COLUMN => 12 ),
  659. -- Display Parameters/Projection Parameters/Rot clkwse.      C4
  660.      ( LINE => 12, COLUMN => 12 ),
  661. -- Display Parameters/Projection Parameters/Satellite alt.   C5
  662.      ( LINE => 13, COLUMN => 12 ),
  663. -- Display Parameters/Projection Parameters/Viewing alt.     C6
  664.      ( LINE => 14, COLUMN => 12 ),
  665.  
  666. -- Display Parameters/Projection Limits/Limit Type.          C7
  667.      ( LINE => 09, COLUMN => 66 ),     
  668. -- Display Parameters/Projection Limits/Limit Min Latitude   C8
  669.      ( LINE => 10, COLUMN => 68 ),     
  670. -- Display Parameters/Projection Limits/Limit Min Longitude  C9
  671.      ( LINE => 11, COLUMN => 68 ),     
  672. -- Display Parameters/Projection Limits/Limit Max Latitude   C10
  673.      ( LINE => 12, COLUMN => 68 ),     
  674. -- Display Parameters/Projection Limits/Limit Max Longitude  C11
  675.      ( LINE => 13, COLUMN => 68 ),     
  676. -- Display Parameters/Projection Limits/Limit North east x   C12
  677.      ( LINE => 10, COLUMN => 68 ),     
  678. -- Display Parameters/Projection Limits/Limit North east y   C13
  679.      ( LINE => 11, COLUMN => 68 ),     
  680. -- Display Parameters/Projection Limits/Limit South west x   C14
  681.      ( LINE => 12, COLUMN => 68 ),     
  682. -- Display Parameters/Projection Limits/Limit South west y   C15
  683.      ( LINE => 13, COLUMN => 68 ),     
  684. -- Display Parameters/Projection Limits/Limit Angle up       C16
  685.      ( LINE => 10, COLUMN => 68 ),     
  686. -- Display Parameters/Projection Limits/Limit Angle down     C17
  687.      ( LINE => 11, COLUMN => 68 ),     
  688. -- Display Parameters/Projection Limits/Limit Angle right    C18
  689.      ( LINE => 12, COLUMN => 68 ),     
  690. -- Display Parameters/Projection Limits/Limit Angle left     C19
  691.      ( LINE => 13, COLUMN => 68 ),     
  692. -- Display Parameters/Projection Limits/Limit Point up x     C20
  693.      ( LINE => 10, COLUMN => 68 ),     
  694. -- Display Parameters/Projection Limits/Limit Point up y     C21
  695.      ( LINE => 11, COLUMN => 68 ),     
  696. -- Display Parameters/Projection Limits/Limit Point down x   C22
  697.      ( LINE => 12, COLUMN => 68 ),     
  698. -- Display Parameters/Projection Limits/Limit Point down y   C23
  699.      ( LINE => 13, COLUMN => 68 ),     
  700. -- Display Parameters/Projection Limits/Limit Point right x  C24
  701.      ( LINE => 14, COLUMN => 68 ),     
  702. -- Display Parameters/Projection Limits/Limit Point right y  C25
  703.      ( LINE => 15, COLUMN => 68 ),     
  704. -- Display Parameters/Projection Limits/Limit Point left x   C26
  705.      ( LINE => 16, COLUMN => 68 ),     
  706. -- Display Parameters/Projection Limits/Limit Point left y   C27
  707.      ( LINE => 17, COLUMN => 68 ),     
  708.  
  709. -- Display Parameters/Color Selection                        C28
  710.      ( LINE => 16, COLUMN => 10 ),
  711. -- Display Parameters/Color Selection/Map outline            C29
  712.      ( LINE => 17, COLUMN => 12 ),
  713. -- Display Parameters/Color Selection/Grid line              C30
  714.      ( LINE => 18, COLUMN => 12 ),
  715. -- Display Parameters/Color Selection/Horizon                C31
  716.      ( LINE => 19, COLUMN => 12 ),
  717. -- Display Parameters/Color Selection/Default                C3A
  718.      ( LINE => 20, COLUMN => 12 ),
  719. -- Display Parameters/Color Selection/Background             C3B
  720.      ( LINE => 21, COLUMN => 12 ),
  721.  
  722. -- Display Parameters/Grid lines                             C32
  723.      ( LINE => 17, COLUMN => 39 ),
  724. -- Display Parameters/Grid lines/Show lines                  C33
  725.      ( LINE => 18, COLUMN => 41 ),
  726. -- Display Parameters/Grid lines/Degrees between latitudes   C34
  727.      ( LINE => 19, COLUMN => 41 ),
  728. -- Display Parameters/Grid lines/Degrees between longitude   C35
  729.      ( LINE => 20, COLUMN => 41 ),
  730. -- Display Parameters/Grid lines/Segment length              C3C
  731.      ( LINE => 21, COLUMN => 41 ),
  732.  
  733. -- Display Parameters/Clipping                               C36
  734. --     ( LINE => 18, COLUMN => 88 ),
  735.  
  736. -- Special Display Functions/Beam Data                       C37
  737.      ( LINE => 12, COLUMN => 10 ),
  738. -- Special Display Functions/Swath Data                      C38
  739.      ( LINE => 13, COLUMN => 10 ),
  740. -- Special Display Functions/Points Data                     C39
  741.      ( LINE => 14, COLUMN => 10 ),
  742. -- Special Display Functions/Beam color                      C40
  743.      ( LINE => 12, COLUMN => 80 ),
  744. -- Special Display Functions/Swath color                     C41
  745.      ( LINE => 13, COLUMN => 80 ),
  746. -- Special Display Functions/Points color                    C42
  747.      ( LINE => 14, COLUMN => 80 ),
  748.  
  749. -- Diagnostics/Warning                                       C43
  750.      ( LINE => 14, COLUMN => 20 ),
  751. -- Diagnostics/Error                                         C44
  752.      ( LINE => 14, COLUMN => 50 ),
  753. -- Diagnostics/Fatal                                         C45
  754.      ( LINE => 14, COLUMN => 80 ),
  755.  
  756. -- Plot characteristics/Axis length x                        C46
  757.      ( LINE => 14, COLUMN => 20 ),
  758. -- Plot characteristics/Axis length y                        C47
  759.      ( LINE => 15, COLUMN => 20 ),
  760. -- Plot characteristics                                      C48
  761.      ( LINE => 14, COLUMN => 70 ),
  762. -- Plot characteristics                                      C49
  763.      ( LINE => 15, COLUMN => 70 ),
  764. -- Session menu filename                                     C50
  765.      ( LINE => 03, COLUMN => 10 ),                                
  766. -- Display menu filename                                     C51
  767.      ( LINE => 03, COLUMN => 10 ),
  768. -- Display Parameters/Show Land                              C52
  769.      ( LINE => 19, COLUMN => 88 )                                );
  770.   
  771.  
  772.   function X_Y_POS_ALT ( ITEM : in FIELD_INDEX ) return TERM_FUNCTIONS.CURSOR_POS;
  773.  
  774. end MENU_CONSTANTS;
  775. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  776. --trigf.sp
  777. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  778. package TRIG_LIB is
  779.   function SIN(X : FLOAT) return FLOAT;
  780.   function COS(X : FLOAT) return FLOAT;
  781.   function TAN(X : FLOAT) return FLOAT;
  782.   function COT(X : FLOAT) return FLOAT;
  783.   function ASIN(X : FLOAT) return FLOAT;
  784.   function ACOS(X : FLOAT) return FLOAT;
  785.   function ATAN(X : FLOAT) return FLOAT;
  786.   function ATAN2(V, U : FLOAT) return FLOAT;
  787.   function SINH(X : FLOAT) return FLOAT;
  788.   function COSH(X : FLOAT) return FLOAT;
  789.   function TANH(X : FLOAT) return FLOAT;
  790. end TRIG_LIB;
  791. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  792. --floatch.sp
  793. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  794. package FLOATING_CHARACTERISTICS is
  795. --  This package is a floating mantissa definition of a binary FLOAT 
  796. --  It was first used on the DEC-10 and the VAX but should work for any
  797. --  since the parameters are obtained by initializing on the actual hardware
  798. --  Otherwise the parameters could be set in the spec if known
  799. --  This is a preliminary package that defines the properties 
  800. --  of the particular floating point type for which we are going to
  801. --  generate the math routines
  802. --  The constants are those required by the routines described in
  803. --  "Software Manual for the Elementary Functions" W. Cody & W. Waite
  804. --  Prentice-Hall 1980
  805. --  Actually most are needed only for the test programs
  806. --  rather than the functions themselves, but might as well be here
  807. --  Most of these could be in the form of attributes if 
  808. --  all the floating types to be considered were those built into the
  809. --  compiler, but we also want to be able to support user defined types
  810. --  such as software floating types of greater precision than
  811. --  the hardware affords, or types defined on one machine to
  812. --  simulate another
  813. --  So we use the Cody-Waite names and derive them from an adaptation of the
  814. --  MACHAR routine as given by Cody-Waite in Appendix B
  815.  
  816.     IBETA : INTEGER;
  817.     --  The radix of the floating-point representation
  818.  
  819.     IT : INTEGER;
  820.     --  The number of base IBETA digits in the DIS_FLOAT significand
  821.  
  822.     IRND : INTEGER;
  823.     --  TRUE (1) if floating addition rounds, FALSE (0) if truncates
  824.  
  825.     NGRD : INTEGER;
  826.     --  Number of guard digits for multiplication
  827.  
  828.     MACHEP : INTEGER;
  829.     --  The largest negative integer such that
  830.     --    1.0 + FLOAT(IBETA) ** MACHEP /= 1.0
  831.     --  except that MACHEP is bounded below by -(IT + 3)
  832.  
  833.     NEGEP : INTEGER;
  834.     --  The largest negative integer such that
  835.     --    1.0 -0 FLOAT(IBETA) ** NEGEP /= 1.0
  836.     --  except that NEGEP is bounded below by -(IT + 3)
  837.  
  838.     IEXP : INTEGER;
  839.     --  The number of bits (decimal places if IBETA = 10)
  840.     --  reserved for the representation of the exponent (including
  841.     --  the bias or sign) of a floating-point number
  842.  
  843.     MINEXP : INTEGER;
  844.     --  The largest in magnitude negative integer such that
  845.     --  FLOAT(IBETA) ** MINEXP is a positive floating-point number
  846.  
  847.  
  848.     MAXEXP : INTEGER;
  849.     --  The largest positive exponent for a finite floating-point number
  850.  
  851.     EPS : FLOAT;
  852.     --  The smallest positive floating-point number such that
  853.     --                              1.0 + EPS /= 1.0
  854.     --  In particular, if IBETA = 2 or IRND = 0,
  855.     --  EPS = FLOAT(IBETA) ** MACHEP
  856.     --  Otherwise, EPS = (FLOAT(IBETA) ** MACHEP) / 2
  857.  
  858.  
  859.     EPSNEG : FLOAT;
  860.     --  A small positive floating-point number such that 1.0-EPSNEG /= 1.0
  861.  
  862.     XMIN : FLOAT;
  863.     --  The smallest non-vanishing floating-point power of the radix
  864.     --  In particular, XMIN = FLOAT(IBETA) ** MINEXP
  865.  
  866.     XMAX : FLOAT;
  867.     --  The largest finite floating-point number
  868.  
  869. --  Here the structure of the floating type is defined
  870. --  I have assumed that the exponent is always some integer form
  871. --  The mantissa can vary
  872. --  Most often it will be a fixed type or the same floating type
  873. --  depending on the most efficient machine implementation
  874. --  Most efficient implementation may require details of the machine hardware
  875. --  In this version the simplest representation is used
  876. --  The mantissa is extracted into a FLOAT and uses the predefined operations
  877.   subtype EXPONENT_TYPE is INTEGER;    --  should be derived  ##########
  878.   subtype MANTISSA_TYPE is FLOAT;     --   range -1.0..1.0;
  879. --  A consequence of the rigorous constraints on MANTISSA_TYPE is that 
  880. --  operations must be very carefully examined to make sure that no number
  881. --  greater than one results
  882. --  Actually this limitation is important in constructing algorithms
  883. --  which will also run when MANTISSA_TYPE is a fixed point type
  884.  
  885. --  If we are not using the STANDARD type, we have to define all the 
  886. --  operations at this point
  887. --  We also need PUT for the type if it is not otherwise available
  888.  
  889. --  Now we do something strange
  890. --  Since we do not know in the following routines whether the mantissa
  891. --  will be carried as a fixed or floating type, we have to make some
  892. --  provision for dividing by two
  893. --  We cannot use the literals, since FIXED/2.0 and FLOAT/2 will fail
  894. --  We define a type-dependent factor that will work
  895.   MANTISSA_DIVISOR_2 : constant FLOAT := 2.0;
  896.   MANTISSA_DIVISOR_3 : constant FLOAT := 3.0;
  897. --  This will work for the MANTISSA_TYPE defined above
  898. --  The alternative of defining an operation "/" to take care of it
  899. --  is too sweeping and would allow unAda-like errors
  900.  
  901.   MANTISSA_HALF : constant MANTISSA_TYPE := 0.5;
  902.  
  903.  
  904.   procedure DEFLOAT(X : in FLOAT;
  905.                     N : out EXPONENT_TYPE; F : out MANTISSA_TYPE);
  906.   procedure REFLOAT(N : in EXPONENT_TYPE; F : in MANTISSA_TYPE; 
  907.                                                    X : out FLOAT);
  908. --  Since the user may wish to define a floating type by some other name
  909. --  CONVERT_TO_FLOAT is used rather than just FLOAT for explicit coersion
  910.   function CONVERT_TO_FLOAT(K : INTEGER) return FLOAT;
  911. --  function CONVERT_TO_FLOAT(N : EXPONENT_TYPE) return FLOAT;
  912.   function CONVERT_TO_FLOAT(F : MANTISSA_TYPE) return FLOAT;
  913.  
  914. end FLOATING_CHARACTERISTICS;
  915.  
  916.  
  917. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  918. --coref.sp
  919. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  920. with FLOATING_CHARACTERISTICS; use FLOATING_CHARACTERISTICS;
  921. package CORE_FUNCTIONS is
  922.  
  923.   EXP_LARGE : FLOAT;
  924.   EXP_SMALL : FLOAT;
  925.  
  926.   function SQRT(X : FLOAT) return FLOAT;
  927.   function CBRT(X : FLOAT) return FLOAT;
  928.   function LOG(X : FLOAT) return FLOAT;
  929.   function LOG10(X : FLOAT) return FLOAT;
  930.   function EXP(X : FLOAT) return FLOAT;
  931.   function "**"(X, Y : FLOAT) return FLOAT;
  932.  
  933. end CORE_FUNCTIONS;
  934. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  935. --numpr.sp
  936. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  937. with FLOATING_CHARACTERISTICS; use FLOATING_CHARACTERISTICS;
  938. package NUMERIC_PRIMITIVES is
  939.  
  940.   --  This may seem a little much but is put in this form to allow the
  941.   --  same form to be used for a generic package
  942.   --  If that is not needed, simple litterals could be substituted
  943.   ZERO  : FLOAT := CONVERT_TO_FLOAT(INTEGER(0));
  944.   ONE   : FLOAT := CONVERT_TO_FLOAT(INTEGER(1));
  945.   TWO   : FLOAT := ONE + ONE;
  946.   THREE : FLOAT := ONE + ONE + ONE;
  947.   HALF  : FLOAT := ONE / TWO;
  948.  
  949.   --  The following "constants" are effectively deferred to
  950.   --  the initialization part of the package body
  951.   --  This is in order to make it possible to generalize the floating type
  952.   --  If that capability is not desired, constants may be included here
  953.   PI            : FLOAT;
  954.   ONE_OVER_PI   : FLOAT;
  955.   TWO_OVER_PI   : FLOAT;
  956.   PI_OVER_TWO   : FLOAT;
  957.   PI_OVER_THREE : FLOAT;
  958.   PI_OVER_FOUR  : FLOAT;
  959.   PI_OVER_SIX   : FLOAT;
  960.  
  961.  
  962.   function SIGN(X, Y : FLOAT) return FLOAT;
  963.     --  Returns the value of X with the sign of Y
  964.   function MAX(X, Y :  FLOAT) return FLOAT;
  965.     --  Returns the algebraicly larger of X and Y
  966.   function TRUNCATE(X : FLOAT) return FLOAT;
  967.     --  Returns the floating value of the integer no larger than X
  968.     --  AINT(X)
  969.   function ROUND(X : FLOAT) return FLOAT;
  970.     --  Returns the floating value nearest X
  971.     --  AINTRND(X)
  972.   function RAN return FLOAT;
  973.     --  This uses a portable algorithm and is included at this point
  974.     --  Algorithms that presume unique machine hardware information
  975.     --  should be initiated in FLOATING_CHARACTERISTICS
  976.  
  977. end NUMERIC_PRIMITIVES;
  978.  
  979.  
  980. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  981. --worldmap.sp
  982. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  983. package World_Map is
  984.  
  985.   procedure Draw_Map;
  986.  
  987. end World_Map;
  988. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  989. --menudraw.txt
  990. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  991. with MENU_CONSTANTS, WORLD_MENUS;
  992. package body MENU_DRAW is
  993.  
  994.   use MENU_CONSTANTS, MENU_TEXT, TERM_FUNCTIONS;
  995.   use WORLD_MENUS, MENU_TYPES, GRAPHIC;
  996.  
  997.   CURRENT_CURSOR_POS                    :      CURSOR_POS;
  998.   BELL_BELL                             :      string ( 1 .. 2 ) := 
  999.                                                 ( 1 .. 2 => ascii.bel );
  1000. -- LEVEL_1 is the entire screen.
  1001.    LEVEL_2                              :      VIEW_PORT;
  1002.    LEVEL_3                              :      VIEW_PORT;
  1003.    LEVEL_4                              :      VIEW_PORT;
  1004.    
  1005.    LEVEL_1_TITLE                        :      VIEW_PORT;
  1006.    LEVEL_1_BODI                         :      VIEW_PORT;
  1007.    LEVEL_1_COMMAND                      :      VIEW_PORT;
  1008.    LEVEL_1_ERRORS                       :      VIEW_PORT;
  1009.  
  1010.    LEVEL_2_TITLE                        :      VIEW_PORT;
  1011.    LEVEL_2_BODI                         :      VIEW_PORT;
  1012.    LEVEL_2_COMMAND                      :      VIEW_PORT;
  1013.  
  1014.    LEVEL_3_TITLE                        :      VIEW_PORT;
  1015.    LEVEL_3_BODI                         :      VIEW_PORT;
  1016.    LEVEL_3_COMMAND                      :      VIEW_PORT;
  1017.    
  1018.    LEVEL_4_TITLE                        :      VIEW_PORT;
  1019.    LEVEL_4_BODI                         :      VIEW_PORT;
  1020.  
  1021.   BLANKS            :      constant string ( 1 .. 50 ) := ( 1 .. 50 => ' ' );
  1022.  
  1023.   SATELITE_DRAWN      :      boolean := false;
  1024.   POINTS_DRAWN        :      boolean := false;
  1025.  
  1026.   procedure DRAW_TEXT ( POSITION : in CURSOR_POS; TEXT : in string ) is
  1027.   begin
  1028.     POSITION_CURSOR ( POSITION );
  1029.     PUT_STRING      ( TEXT );
  1030.   end DRAW_TEXT;    
  1031.   
  1032.   procedure DRAW_PAIR ( POSITION : in CURSOR_POS; TEXT  : in string;
  1033.                         ALT_POS  : in CURSOR_POS; TEXT1 : in string ) is
  1034.     TEMP      :      integer := 1;
  1035.   begin
  1036.     DRAW_TEXT ( POSITION, TEXT  );
  1037.     TEMP := ALT_POS.COLUMN - ( POSITION.COLUMN + TEXT'LENGTH - 1 );
  1038.     PUT_STRING ( BLANKS ( 1 .. TEMP ) );
  1039.     DRAW_TEXT ( ALT_POS , TEXT1 );
  1040.   end DRAW_PAIR;
  1041.  
  1042.   procedure FRM_PORT ( PORT : in VIEW_PORT; FRAME_COLOR : in COLOR_TYPE ) is
  1043.   begin
  1044.     SELECT_PORT ( PORT );
  1045.     SET_COLOR   ( FRAME_COLOR );
  1046.     FRAME_PORT;
  1047.   end FRM_PORT;
  1048.  
  1049.   procedure CLEAR ( PORT : in VIEW_PORT ) is
  1050.   begin
  1051.     SELECT_PORT ( PORT );
  1052.     ERASE_PORT  ( BLACK );
  1053.   end CLEAR;
  1054.  
  1055.   procedure DRAW_PORT_TEXT ( PORT : in VIEW_PORT; POSITION : in CURSOR_POS;
  1056.                              TEXT : in string; FRAME_COLOR : in COLOR_TYPE 
  1057.                                                := BLUE ) is
  1058.   begin
  1059.     DRAW_TEXT ( POSITION, TEXT ( TEXT'first .. TEXT'last ) );
  1060.     FRM_PORT  ( PORT, FRAME_COLOR );
  1061.   end DRAW_PORT_TEXT;
  1062.  
  1063.   procedure MAP_TITLE_FIELD is
  1064.   begin
  1065.     DRAW_PAIR ( X_Y_POS ( CI0 )    , C0,
  1066.                 X_Y_POS_ALT ( CI0 ), CURRENT_TITLE );
  1067.   end MAP_TITLE_FIELD;
  1068.  
  1069.   procedure DRAW_PROJ_PARAM_FIELDS ( OMIT : in boolean := false ) is
  1070.     TEMP_TYPE :      KIND_OF_PROJECTION;
  1071.     TEMP      :      PROJECTION_PARAMETERS;
  1072.   begin
  1073.     TEMP_TYPE := TYPE_OF_PROJECTION;
  1074.     TEMP := CURRENT_PROJECTION_PARAMETERS;
  1075.     if not OMIT then
  1076.       DRAW_PAIR ( X_Y_POS ( CI1 )    , C1,
  1077.                   X_Y_POS_ALT ( CI1 ), 
  1078.                   KIND_OF_PROJECTION'image ( TEMP_TYPE ) );
  1079.     else
  1080.       DRAW_TEXT ( X_Y_POS_ALT ( CI1 ),
  1081.                   BLANKS ( 1 .. 15 ) );
  1082.       DRAW_TEXT ( X_Y_POS_ALT ( CI1 ),
  1083.                   KIND_OF_PROJECTION'image ( TEMP_TYPE ) );
  1084.     end if;
  1085.     DRAW_PAIR ( X_Y_POS ( CI2 )    , C2,
  1086.                 X_Y_POS_ALT ( CI2 ), 
  1087.                 FL_STRING ( TEMP.LAT_CENTER )        );
  1088.     DRAW_PAIR ( X_Y_POS ( CI3 )    , C3,
  1089.                 X_Y_POS_ALT ( CI3 ),
  1090.                 FL_STRING ( TEMP.LON_CENTER )        );
  1091.     DRAW_PAIR ( X_Y_POS ( CI4 )    , C4,
  1092.                 X_Y_POS_ALT ( CI4 ),
  1093.                 FL_STRING ( TEMP.CLK_ROT_AR_CENT ));
  1094.  
  1095.     if ( TEMP_TYPE /= SATELLITE ) and then SATELITE_DRAWN then
  1096.       DRAW_PAIR ( X_Y_POS ( CI5 )    , BLANKS ( 1 .. C5'length ),
  1097.                   X_Y_POS_ALT ( CI5 ),
  1098.                   BLANKS ( 1 .. 13 )      );
  1099.       DRAW_PAIR ( X_Y_POS ( CI6 )    , BLANKS ( 1 .. C6'LENGTH ),
  1100.                   X_Y_POS_ALT ( CI6 ),
  1101.                   BLANKS ( 1 .. 13 )      );
  1102.     end if;
  1103.  
  1104.     if TEMP_TYPE = SATELLITE then
  1105.       SATELITE_DRAWN := true;
  1106.       DRAW_PAIR ( X_Y_POS ( CI5 )    , C5,
  1107.                   X_Y_POS_ALT ( CI5 ),
  1108.                   FL_STRING ( TEMP.SAT_ALTITUDE )    );
  1109.       DRAW_PAIR ( X_Y_POS ( CI6 )    , C6,
  1110.                   X_Y_POS_ALT ( CI6 ),
  1111.                   FL_STRING ( TEMP.VIEW_ALTITUDE )   );
  1112.     else
  1113.       SATELITE_DRAWN := false;
  1114.     end if;
  1115.   end DRAW_PROJ_PARAM_FIELDS;
  1116.  
  1117.   procedure DRAW_PROJ_LIMIT_FIELDS ( OMIT : in boolean := false ) is
  1118.     TEMP_TYPE      :      KIND_OF_PROJECTION_LIMIT;
  1119.     TEMP           :      PROJECTION_LIMITS;
  1120.   begin
  1121.     TEMP_TYPE := TYPE_OF_PROJECTION_LIMIT;
  1122.     TEMP      := CURRENT_PROJECTION_LIMITS;
  1123.     if not OMIT then
  1124.       DRAW_PAIR ( X_Y_POS ( CI7 )    , C7,
  1125.                   X_Y_POS_ALT ( CI7 ), 
  1126.                   KIND_OF_PROJECTION_LIMIT'image 
  1127.                     ( TEMP_TYPE ) );
  1128.     else
  1129.       DRAW_TEXT ( X_Y_POS_ALT ( CI7 ),
  1130.                   BLANKS ( 1 .. 35 ) );
  1131.       DRAW_TEXT ( X_Y_POS_ALT ( CI7 ),
  1132.                   KIND_OF_PROJECTION_LIMIT'image ( TEMP_TYPE ) );
  1133.     end if;
  1134.  
  1135.     if ( TEMP_TYPE /= LAT_LON_BOUNDARY ) and then POINTS_DRAWN then
  1136.       DRAW_PAIR ( X_Y_POS ( CI24 )    , BLANKS ( 1 .. C24'length ),
  1137.                   X_Y_POS_ALT ( CI24 ), 
  1138.                   BLANKS ( 1 .. 13 ) );
  1139.       DRAW_PAIR ( X_Y_POS ( CI25 )    , BLANKS ( 1 .. C25'length ),
  1140.                   X_Y_POS_ALT ( CI25 ), 
  1141.                   BLANKS ( 1 .. 13 ) );
  1142.       DRAW_PAIR ( X_Y_POS ( CI26 )    , BLANKS ( 1 .. C26'length ),
  1143.                   X_Y_POS_ALT ( CI26 ), 
  1144.                   BLANKS ( 1 .. 13 ) );
  1145.       DRAW_PAIR ( X_Y_POS ( CI27 )    , BLANKS ( 1 .. C27'length ),
  1146.                   X_Y_POS_ALT ( CI27 ), 
  1147.                   BLANKS ( 1 .. 13 ) );
  1148.     end if;
  1149.     
  1150.     POINTS_DRAWN := false;
  1151.     case TEMP_TYPE is
  1152.       when ALL_EARTH                               =>
  1153.         DRAW_PAIR ( X_Y_POS ( CI8 )    , BLANKS ( 1 .. C8'length ),
  1154.                     X_Y_POS_ALT ( CI8 ), 
  1155.                     BLANKS ( 1 .. 13 ) );
  1156.         DRAW_PAIR ( X_Y_POS ( CI9 )    , BLANKS ( 1 .. C9'length ),
  1157.                     X_Y_POS_ALT ( CI9 ), 
  1158.                     BLANKS ( 1 .. 13 ) );
  1159.         DRAW_PAIR ( X_Y_POS ( CI10 )    , BLANKS ( 1 .. C10'length ),
  1160.                     X_Y_POS_ALT ( CI10 ), 
  1161.                     BLANKS ( 1 .. 13 ) );
  1162.         DRAW_PAIR ( X_Y_POS ( CI11 )    , BLANKS ( 1 .. C11'length ),
  1163.                     X_Y_POS_ALT ( CI11 ), 
  1164.                     BLANKS ( 1 .. 13 ) );
  1165.       when MIN_MAX_LAT_LON                         =>
  1166.         DRAW_PAIR ( X_Y_POS ( CI8 )    , C8,
  1167.                     X_Y_POS_ALT ( CI8 ), 
  1168.                     FL_STRING ( TEMP.MIN_LAT_LON.X ) );
  1169.         DRAW_PAIR ( X_Y_POS ( CI9 )    , C9,
  1170.                     X_Y_POS_ALT ( CI9 ), 
  1171.                     FL_STRING ( TEMP.MIN_LAT_LON.Y ) );
  1172.         DRAW_PAIR ( X_Y_POS ( CI10 )    , C10,
  1173.                     X_Y_POS_ALT ( CI10 ), 
  1174.                     FL_STRING ( TEMP.MAX_LAT_LON.X ) );
  1175.         DRAW_PAIR ( X_Y_POS ( CI11 )    , C11,
  1176.                     X_Y_POS_ALT ( CI11 ), 
  1177.                     FL_STRING ( TEMP.MAX_LAT_LON.Y ) );
  1178.  
  1179.       when MIN_MAX_COORDINATES                     =>
  1180.         DRAW_PAIR ( X_Y_POS ( CI12 )    , C12,
  1181.                     X_Y_POS_ALT ( CI12 ), 
  1182.                     FL_STRING ( TEMP.NORTH_EAST.X ) );
  1183.         DRAW_PAIR ( X_Y_POS ( CI13 )    , C13,
  1184.                     X_Y_POS_ALT ( CI13 ), 
  1185.                     FL_STRING ( TEMP.NORTH_EAST.Y ) );
  1186.         DRAW_PAIR ( X_Y_POS ( CI14 )    , C14,
  1187.                     X_Y_POS_ALT ( CI14 ), 
  1188.                     FL_STRING ( TEMP.SOUTH_WEST.X ) );
  1189.         DRAW_PAIR ( X_Y_POS ( CI15 )    , C15,
  1190.                     X_Y_POS_ALT ( CI15 ), 
  1191.                     FL_STRING ( TEMP.SOUTH_WEST.Y ) );
  1192.  
  1193.      when ANGULAR_DIST_FROM_PROJECTION_CENTER =>
  1194.         DRAW_PAIR ( X_Y_POS ( CI16 )    , C16,
  1195.                     X_Y_POS_ALT ( CI16 ), 
  1196.                     FL_STRING ( TEMP.ANGLE_UP    ) );
  1197.         DRAW_PAIR ( X_Y_POS ( CI17 )    , C17,
  1198.                     X_Y_POS_ALT ( CI17 ), 
  1199.                     FL_STRING ( TEMP.ANGLE_DOWN  ) );
  1200.         DRAW_PAIR ( X_Y_POS ( CI18 )    , C18,
  1201.                     X_Y_POS_ALT ( CI18 ), 
  1202.                     FL_STRING ( TEMP.ANGLE_RIGHT ) );
  1203.         DRAW_PAIR ( X_Y_POS ( CI19 )    , C19,
  1204.                     X_Y_POS_ALT ( CI19 ), 
  1205.                     FL_STRING ( TEMP.ANGLE_LEFT  ) );
  1206.  
  1207.       when LAT_LON_BOUNDARY                        =>
  1208.         POINTS_DRAWN := true;
  1209.         DRAW_PAIR ( X_Y_POS ( CI20 )    , C20,
  1210.                     X_Y_POS_ALT ( CI20 ), 
  1211.                     FL_STRING ( TEMP.POINT_UP.X     ) );
  1212.         DRAW_PAIR ( X_Y_POS ( CI21 )    , C21,
  1213.                     X_Y_POS_ALT ( CI21 ), 
  1214.                     FL_STRING ( TEMP.POINT_UP.Y     ) );
  1215.         DRAW_PAIR ( X_Y_POS ( CI22 )    , C22,
  1216.                     X_Y_POS_ALT ( CI22 ), 
  1217.                     FL_STRING ( TEMP.POINT_DOWN.X   ) );
  1218.         DRAW_PAIR ( X_Y_POS ( CI23 )    , C23,
  1219.                     X_Y_POS_ALT ( CI23 ), 
  1220.                     FL_STRING ( TEMP.POINT_DOWN.Y   ) );
  1221.         DRAW_PAIR ( X_Y_POS ( CI24 )    , C24,
  1222.                     X_Y_POS_ALT ( CI24 ), 
  1223.                     FL_STRING ( TEMP.POINT_RIGHT.X     ) );
  1224.         DRAW_PAIR ( X_Y_POS ( CI25 )    , C25,
  1225.                     X_Y_POS_ALT ( CI25 ), 
  1226.                     FL_STRING ( TEMP.POINT_RIGHT.Y     ) );
  1227.         DRAW_PAIR ( X_Y_POS ( CI26 )    , C26,
  1228.                     X_Y_POS_ALT ( CI26 ), 
  1229.                     FL_STRING ( TEMP.POINT_LEFT.X   ) );
  1230.         DRAW_PAIR ( X_Y_POS ( CI27 )    , C27,
  1231.                     X_Y_POS_ALT ( CI27 ), 
  1232.                     FL_STRING ( TEMP.POINT_LEFT.Y   ) );
  1233.       when others                                  =>
  1234.         null;
  1235.     end case;
  1236.   end DRAW_PROJ_LIMIT_FIELDS;
  1237.   
  1238.   procedure CS_FIELD is
  1239.     TEMP      :      COLOR_SELECTION;
  1240.   begin
  1241.     TEMP := CURRENT_COLOR_SELECTION;
  1242.     DRAW_TEXT ( X_Y_POS ( CI28 ), C28 );
  1243.  
  1244.     DRAW_PAIR ( X_Y_POS ( CI29 )    , C29,
  1245.                 X_Y_POS_ALT ( CI29 ), 
  1246.                 COLOR_TYPE'image ( TEMP.MAP_OUTLINE ) );
  1247.     DRAW_PAIR ( X_Y_POS ( CI30 )    , C30,
  1248.                 X_Y_POS_ALT ( CI30 ), 
  1249.                 COLOR_TYPE'image ( TEMP.GRID_LINES  ) );
  1250.     DRAW_PAIR ( X_Y_POS ( CI31 )    , C31,
  1251.                 X_Y_POS_ALT ( CI31 ), 
  1252.                 COLOR_TYPE'image ( TEMP.HORIZON     ) );
  1253.     DRAW_PAIR ( X_Y_POS ( CI3A )    , C3A,
  1254.                 X_Y_POS_ALT ( CI3A ), 
  1255.                 COLOR_TYPE'image ( TEMP.DEFAULT     ) );
  1256.     DRAW_PAIR ( X_Y_POS ( CI3B )    , C3B,
  1257.                 X_Y_POS_ALT ( CI3B ), 
  1258.                 COLOR_TYPE'image ( TEMP.BACKGROUND  ) );
  1259.   end CS_FIELD;
  1260.  
  1261.   procedure GL_FIELD is
  1262.     TEMP      :      GRID_LINE_PARAMETERS;
  1263.   begin
  1264.     TEMP := CURRENT_GRID_LINE_PARAMETERS;
  1265.     DRAW_TEXT ( X_Y_POS ( CI32 ), C32 ); 
  1266.  
  1267.     DRAW_PAIR ( X_Y_POS ( CI33 )    , C33,
  1268.                 X_Y_POS_ALT ( CI33 ), 
  1269.                 boolean'image ( TEMP.SHOW_LINES ) );
  1270.     DRAW_PAIR ( X_Y_POS ( CI34 )    , C34,
  1271.                 X_Y_POS_ALT ( CI34 ), 
  1272.                 FL_STRING ( TEMP.DEGREES_BTWN_LATS ) );
  1273.     DRAW_PAIR ( X_Y_POS ( CI35 )    , C35,
  1274.                 X_Y_POS_ALT ( CI35 ), 
  1275.                 FL_STRING ( TEMP.DEGREES_BTWN_LONS ) );
  1276.     DRAW_PAIR ( X_Y_POS ( CI3C )    , C3C,
  1277.                 X_Y_POS_ALT ( CI3C ), 
  1278.                 FL_STRING ( TEMP.SEGMENT_LENGTH ) );
  1279.   end GL_FIELD;
  1280.  
  1281.   procedure CLP_FIELD is
  1282.   begin
  1283. --    DRAW_PAIR ( X_Y_POS ( CI36 )    , C36,
  1284. --                X_Y_POS_ALT ( CI36 ), 
  1285. --                boolean'image ( CLIPPING ));
  1286.     DRAW_PAIR ( X_Y_POS ( CI52 )    , C52,
  1287.                 X_Y_POS_ALT ( CI52 ), 
  1288.                 boolean'image ( PLOT_LAND ));
  1289.   end CLP_FIELD;
  1290.  
  1291.   procedure DRAW_ERROR_PORT ( TEXT1 : in string; TEXT : in string ) is
  1292.     CH      :      character      := ' ';
  1293.   begin
  1294.     PUT_STRING ( BELL_BELL );
  1295.     CURRENT_CURSOR_POS := ( 02, COM_1_INDENT );
  1296.     DRAW_TEXT      ( CURRENT_CURSOR_POS, TEXT1 ( TEXT1'first .. TEXT1'last ) );
  1297.     CURRENT_CURSOR_POS.LINE := CURRENT_CURSOR_POS.LINE + 1;
  1298.     DRAW_TEXT      ( CURRENT_CURSOR_POS, TEXT  ( TEXT'first .. TEXT'last )   );
  1299.     CURRENT_CURSOR_POS.LINE   := CURRENT_CURSOR_POS.LINE + 1;
  1300.     CURRENT_CURSOR_POS.COLUMN := CURRENT_CURSOR_POS.COLUMN + 5;
  1301.     DRAW_PORT_TEXT ( LEVEL_1_ERRORS, CURRENT_CURSOR_POS, 
  1302.                      "Hit any character to continue =>", RED );
  1303.     GET_CHAR ( CH );
  1304.     CLEAR          ( LEVEL_1_ERRORS );
  1305.     FRM_PORT ( LEVEL_1_BODI, BLUE );
  1306.   end DRAW_ERROR_PORT;
  1307.  
  1308.   procedure DRAW_COMMAND ( LEVEL : in NESTED_LEVEL;
  1309.                            TEXT  : in string                        ) is
  1310.  
  1311.  
  1312.   begin
  1313.     
  1314.     case LEVEL is
  1315.       when ONE   =>
  1316.         CURRENT_CURSOR_POS := ( HEIGHT_MAX, COM_1_INDENT );
  1317.         DRAW_PORT_TEXT ( LEVEL_1_COMMAND, 
  1318.             CURRENT_CURSOR_POS, TEXT ( TEXT'first .. TEXT'last ) );
  1319.       when TWO   =>
  1320.         CURRENT_CURSOR_POS := ( HEIGHT_MAX - 2, COM_2_INDENT );
  1321.         DRAW_PORT_TEXT ( LEVEL_2_COMMAND, 
  1322.             CURRENT_CURSOR_POS, TEXT ( TEXT'first .. TEXT'last ) );
  1323.       when THREE =>
  1324.         CURRENT_CURSOR_POS := ( HEIGHT_MAX - 4, COM_3_INDENT );
  1325.         DRAW_PORT_TEXT ( LEVEL_3_COMMAND, 
  1326.             CURRENT_CURSOR_POS, TEXT ( TEXT'first .. TEXT'last ) );
  1327.       when others =>
  1328.         null;
  1329.     end case;
  1330.  
  1331.   end DRAW_COMMAND;
  1332.  
  1333.   procedure DRAW_DP_MENU ( LEVEL : in NESTED_LEVEL ) is
  1334.   begin
  1335.  
  1336.     if LEVEL = ONE then
  1337.       ERASE_SCREEN;
  1338.       CURRENT_CURSOR_POS := ( COM_1_INDENT - 4, DP_T_LEV_1 );
  1339.       DRAW_PORT_TEXT ( LEVEL_1_TITLE, CURRENT_CURSOR_POS, DP_TITLE_LINE );
  1340.     else
  1341.       CLEAR ( LEVEL_2 );
  1342.       CURRENT_CURSOR_POS := ( COM_2_INDENT - 5, DP_T_LEV_2 );
  1343.       DRAW_PORT_TEXT ( LEVEL_2_TITLE, CURRENT_CURSOR_POS, DP_TITLE_LINE );
  1344.     end if;
  1345.  
  1346.     MAP_TITLE_FIELD;
  1347.     DRAW_PROJ_PARAM_FIELDS;
  1348.     DRAW_PROJ_LIMIT_FIELDS;
  1349.     CS_FIELD;
  1350.     GL_FIELD;
  1351.     CLP_FIELD;
  1352.  
  1353.     if LEVEL = ONE then
  1354.       FRM_PORT     ( LEVEL_1_BODI, BLUE );
  1355.       DRAW_COMMAND ( ONE, CL1 );
  1356.     else
  1357.       FRM_PORT     ( LEVEL_2_BODI, BLUE );
  1358.     end if;
  1359.  
  1360.   end DRAW_DP_MENU;
  1361.  
  1362.   procedure DRAW_SDF_MENU ( CMD_DRAW : in boolean := true ) is
  1363.     TEMP      :      SPECIAL_DISPLAYS;
  1364.   begin
  1365.     TEMP := CURRENT_SPECIAL_DISPLAYS;
  1366.     CLEAR          ( LEVEL_3 );
  1367.     CURRENT_CURSOR_POS := ( COM_3_INDENT - 8, SDF_T_LEV_3 );
  1368.  
  1369.     DRAW_PORT_TEXT ( LEVEL_3_TITLE, CURRENT_CURSOR_POS, SDF_TITLE );
  1370.  
  1371.     DRAW_PAIR ( X_Y_POS ( CI37 )    , C37,
  1372.                 X_Y_POS_ALT ( CI37 ), 
  1373.                 TEMP.BEAM_DATA            );
  1374.  
  1375.     DRAW_PAIR ( X_Y_POS ( CI38 )    , C38,
  1376.                 X_Y_POS_ALT ( CI38 ), 
  1377.                 TEMP.SWATH_DATA           );
  1378.  
  1379.     DRAW_PAIR ( X_Y_POS ( CI39 )    , C39,
  1380.                 X_Y_POS_ALT ( CI39 ), 
  1381.                 TEMP.POINTS_DATA          );
  1382.  
  1383.     DRAW_PAIR ( X_Y_POS ( CI40 )    , C40,
  1384.                 X_Y_POS_ALT ( CI40 ), 
  1385.                 COLOR_TYPE'image ( TEMP.BEAM_COLOR ) );
  1386.  
  1387.     DRAW_PAIR ( X_Y_POS ( CI41 )    , C41,
  1388.                 X_Y_POS_ALT ( CI41 ), 
  1389.                 COLOR_TYPE'image ( TEMP.SWATH_COLOR ) );
  1390.  
  1391.     DRAW_PAIR ( X_Y_POS ( CI42 )    , C42,
  1392.                 X_Y_POS_ALT ( CI42 ), 
  1393.                 COLOR_TYPE'image ( TEMP.POINTS_COLOR ) );
  1394.  
  1395.     FRM_PORT       ( LEVEL_3_BODI, BLUE );
  1396.     if CMD_DRAW then
  1397.       DRAW_COMMAND   ( THREE, CL2 );
  1398.     end if;
  1399.   end DRAW_SDF_MENU;
  1400.  
  1401.   procedure DRAW_DIG_MENU is
  1402.     TEMP      :      DIAGNOSTICS;
  1403.   begin
  1404.     TEMP := CURRENT_DIAGNOSTICS;
  1405.     CLEAR          ( LEVEL_4 );
  1406.     CURRENT_CURSOR_POS := ( COM_4_INDENT - 11, DIG_T_LEV_4 );
  1407.  
  1408.     DRAW_PORT_TEXT ( LEVEL_4_TITLE, CURRENT_CURSOR_POS, DIG_TITLE );
  1409.  
  1410.     DRAW_PAIR ( X_Y_POS ( CI43 )    , C43,
  1411.                 X_Y_POS_ALT ( CI43 ), 
  1412.                 boolean'image ( TEMP.WARNING )      );
  1413.  
  1414.     DRAW_PAIR ( X_Y_POS ( CI44 )    , C44,
  1415.                 X_Y_POS_ALT ( CI44 ), 
  1416.                 boolean'image ( TEMP.ERROR )        );
  1417.  
  1418.     DRAW_PAIR ( X_Y_POS ( CI45 )    , C45,
  1419.                 X_Y_POS_ALT ( CI45 ), 
  1420.                 boolean'image ( TEMP.FATAL )        );
  1421.  
  1422.     FRM_PORT       ( LEVEL_4_BODI, BLUE );
  1423.   end DRAW_DIG_MENU;
  1424.  
  1425.   procedure DRAW_PLC_MENU is
  1426.     TEMP      :      PLOT_CHARACTERISTICS;
  1427.   begin
  1428.     TEMP := CURRENT_PLOT_CHAR;
  1429.     CLEAR          ( LEVEL_4 );
  1430.     CURRENT_CURSOR_POS := ( COM_4_INDENT - 11, PLC_T_LEV_4 );
  1431.  
  1432.     DRAW_PORT_TEXT ( LEVEL_4_TITLE, CURRENT_CURSOR_POS, PLC_TITLE );
  1433.  
  1434.     DRAW_PAIR ( X_Y_POS ( CI46 )    , C46,
  1435.                 X_Y_POS_ALT ( CI46 ), 
  1436.                 FL_STRING ( TEMP.AXIS_LENGTH.X ) );
  1437.  
  1438.     DRAW_PAIR ( X_Y_POS ( CI47 )    , C47,
  1439.                 X_Y_POS_ALT ( CI47 ), 
  1440.                 FL_STRING ( TEMP.AXIS_LENGTH.Y ) );
  1441.  
  1442.     DRAW_PAIR ( X_Y_POS ( CI48 )    , C48,
  1443.                 X_Y_POS_ALT ( CI48 ), 
  1444.                 FL_STRING ( TEMP.ORIGIN.X      ) );
  1445.  
  1446.     DRAW_PAIR ( X_Y_POS ( CI49 )    , C49,
  1447.                 X_Y_POS_ALT ( CI49 ), 
  1448.                 FL_STRING ( TEMP.ORIGIN.Y      ) );
  1449.  
  1450.     FRM_PORT       ( LEVEL_4_BODI, BLUE );
  1451.   end DRAW_PLC_MENU;
  1452.  
  1453.   procedure DRAW_SESSION_MENU is
  1454.   begin
  1455.     ERASE_SCREEN;
  1456.     CURRENT_CURSOR_POS      := ( COM_1_INDENT - 4, SES_T_LEV_1 );
  1457.     DRAW_PORT_TEXT ( LEVEL_1_TITLE, CURRENT_CURSOR_POS, SES_TITLE );
  1458.     FRM_PORT       ( LEVEL_1_BODI, BLUE );
  1459.     DRAW_COMMAND   ( ONE, CL3 );
  1460.   end DRAW_SESSION_MENU; 
  1461.  
  1462.   procedure DRAW_MAP_MENU is
  1463.   begin
  1464.     ERASE_SCREEN;
  1465.     CURRENT_CURSOR_POS      := ( COM_1_INDENT - 4, MAP_T_LEV_1 );
  1466.     MAP_TITLEM ( 8 .. MAP_TITLEM'last ) := CURRENT_TITLE;
  1467.     DRAW_PORT_TEXT ( LEVEL_1_TITLE, CURRENT_CURSOR_POS, MAP_TITLEM );
  1468.     FRM_PORT       ( LEVEL_1_BODI, BLUE );
  1469.     DRAW_COMMAND   ( ONE, CL4 );
  1470.   end DRAW_MAP_MENU;
  1471.  
  1472. --  procedure DRAW_HELP_MENU is
  1473. --  begin
  1474. --    CLEAR          ( LEVEL_2 );
  1475. --    CURRENT_CURSOR_POS      := ( COM_2_INDENT - 5, HTOP_LEV_2 );
  1476. --    DRAW_PORT_TEXT ( LEVEL_2_TITLE, CURRENT_CURSOR_POS, HTOP_TITLE );
  1477. --    FRM_PORT       ( LEVEL_2_BODI, BLUE );
  1478. --    DRAW_COMMAND   ( TWO, CL5 );
  1479. --  end;
  1480.  
  1481.   procedure DRAW_SESSION_FILENAME is
  1482.   begin
  1483.     DRAW_PAIR ( X_Y_POS ( CI50 ), C50,
  1484.                 X_Y_POS_ALT ( CI50 ), BLANKS );
  1485.   end DRAW_SESSION_FILENAME;
  1486.  
  1487.   procedure DRAW_DISPLAY_FILENAME is
  1488.   begin
  1489.     DRAW_PAIR ( X_Y_POS ( CI51 ), C51,
  1490.                 X_Y_POS_ALT ( CI51 ), BLANKS );
  1491.   end DRAW_DISPLAY_FILENAME;
  1492.  
  1493. --  procedure DRAW_HELP_SUB_MENU is
  1494. --  begin
  1495. --    CLEAR          ( LEVEL_3 );
  1496. --    CURRENT_CURSOR_POS      := ( COM_3_INDENT - 8, HTOP_LEV_3 );
  1497. --    DRAW_PORT_TEXT ( LEVEL_3_TITLE, CURRENT_CURSOR_POS, HTOP_TITLE );
  1498. --    FRM_PORT       ( LEVEL_3_BODI, BLUE );
  1499. --    DRAW_COMMAND   ( THREE, CL5 );
  1500. --  end;
  1501.  
  1502.   procedure INITIALIZE_MENUS is
  1503.   begin
  1504.     SET_TOP_AND_BOTTOM_MARGINS ( 0, HEIGHT_MAX );
  1505.     SET_HOME;
  1506.     SET_132_COLUMNS_PER_LINE;
  1507.  
  1508.     NEW_SCREEN_SIZE ( WIDTH_MAX, HEIGHT_MAX );
  1509.     CURSOR_HOME;
  1510.  
  1511.  -- LEVEL_1 is the entire screen.
  1512.   
  1513.     CREATE_PORT ( LEVEL_2,         04, 04, LEVEL_2_WIDTH, LEVEL_2_HEIGHT );
  1514.     CREATE_PORT ( LEVEL_3,         06, 06, LEVEL_3_WIDTH, LEVEL_3_HEIGHT );
  1515.     CREATE_PORT ( LEVEL_4,         08, 08, LEVEL_4_WIDTH, LEVEL_4_HEIGHT );
  1516.    
  1517.     CREATE_PORT ( LEVEL_1_TITLE,   00, 00, WIDTH_MAX    , 01 );
  1518.     CREATE_PORT ( LEVEL_1_BODI,    00, 01, WIDTH_MAX    , 22 );
  1519.     CREATE_PORT ( LEVEL_1_COMMAND, 00, HEIGHT_MAX - 1, WIDTH_MAX    , 01 );
  1520.     CREATE_PORT ( LEVEL_1_ERRORS,  04, 01, LEVEL_2_WIDTH, 03 );
  1521.  
  1522.     CREATE_PORT ( LEVEL_2_TITLE,   04, 04, LEVEL_2_WIDTH, 01                 );
  1523.     CREATE_PORT ( LEVEL_2_BODI,    04, 05, LEVEL_2_WIDTH, LEVEL_2_HEIGHT - 1 );
  1524.     CREATE_PORT ( LEVEL_2_COMMAND, 04, 21, LEVEL_2_WIDTH, 01                 );
  1525.  
  1526.     CREATE_PORT ( LEVEL_3_TITLE,   06, 06, LEVEL_3_WIDTH, 01                 );
  1527.     CREATE_PORT ( LEVEL_3_BODI,    06, 07, LEVEL_3_WIDTH, LEVEL_3_HEIGHT - 1 );
  1528.     CREATE_PORT ( LEVEL_3_COMMAND, 06, 19, LEVEL_3_WIDTH, 01                 );
  1529.  
  1530.     CREATE_PORT ( LEVEL_4_TITLE,   08, 08, LEVEL_4_WIDTH, 01                 );
  1531.     CREATE_PORT ( LEVEL_4_BODI,    08, 09, LEVEL_4_WIDTH, LEVEL_4_HEIGHT - 1 );
  1532.  
  1533.     DRAW_SESSION_MENU;
  1534.     DRAW_DP_MENU ( TWO );
  1535.   
  1536.   end INITIALIZE_MENUS;
  1537.  
  1538. begin 
  1539.   null;
  1540. end MENU_DRAW;
  1541. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1542. --menuparse.txt
  1543. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1544. with MENU_CONSTANTS, MENU_CURRENTS, MENU_DRAW, MENU_FILE_IO;
  1545. package body MENU_PARSE is
  1546.  
  1547.   use  MENU_CURRENTS,  MENU_TYPES,     MENU_FILE_IO;
  1548.   use  MENU_CONSTANTS, TERM_FUNCTIONS, MENU_TEXT, MENU_DRAW, GRAPHIC;
  1549.  
  1550.   CURRENT_MEN             :      MENUS             := SESSION;
  1551.   CURRENT_COM_FIELD       :      integer range 0 .. FIELD_4_MAX + 1 := 0;
  1552.   CURRENT_CURSOR_POS      :      CURSOR_POS        := ( 0, 0 );
  1553.   CURRENT_TOKEN           :      TOKEN             := ALPHA_NUM;
  1554.   CUR_INDEX               :      FIELD_INDEX       := CI0;
  1555.  
  1556.   TEMP_COMMAND            :      COMMAND           := QUIT;
  1557.  
  1558.   FLOAT_INC               :      constant FLOAT    := 10.0;
  1559.  
  1560.   BLANK_STRING            :      string ( 1 .. 40 ) := ( 1 .. 40 => ' ' );
  1561.   HOLD_STRING             :      string ( 1 .. 40 ) := ( 1 .. 40 => ' ' );
  1562.   LAST                    :      integer      := 0;
  1563.  
  1564.   procedure SET_COM_CURSOR ( COM_LINE, INDENT : in integer ) is
  1565.   begin
  1566.     CURRENT_CURSOR_POS := ( COM_LINE, INDENT + COM_FIE_OFF ( CURRENT_COM_FIELD ) );
  1567.     POSITION_CURSOR ( CURRENT_CURSOR_POS );
  1568.   end SET_COM_CURSOR;
  1569.  
  1570.   procedure MOVE_RIGHT ( COM_LINE, MAX_FIELDS, INDENT : in integer ) is
  1571.   begin
  1572.     if CURRENT_COM_FIELD = MAX_FIELDS then
  1573.       CURRENT_COM_FIELD := 0;
  1574.     end if;
  1575.     CURRENT_COM_FIELD := CURRENT_COM_FIELD + 1;
  1576.     SET_COM_CURSOR ( COM_LINE, INDENT );
  1577.   end MOVE_RIGHT;
  1578.  
  1579.   procedure MOVE_LEFT ( COM_LINE, MAX_FIELDS, INDENT : in integer ) is
  1580.   begin
  1581.     if CURRENT_COM_FIELD = 1 then
  1582.       CURRENT_COM_FIELD := MAX_FIELDS + 1;
  1583.     end if;
  1584.     CURRENT_COM_FIELD := CURRENT_COM_FIELD - 1;
  1585.     SET_COM_CURSOR ( COM_LINE, INDENT );
  1586.   end MOVE_LEFT;
  1587.  
  1588.   procedure PARSE_COMMAND ( COM_LINE, MAX_FIELD, INDENT : in integer ) is
  1589.   begin
  1590.     loop
  1591.       CURRENT_TOKEN := PARSE_INPUT;
  1592.       case CURRENT_TOKEN is
  1593.         when TAB        | RIGHT_ARROW =>
  1594.           MOVE_RIGHT ( COM_LINE, MAX_FIELD, INDENT);
  1595.         when BACK_SPACE | LEFT_ARROW  =>
  1596.           MOVE_LEFT ( COM_LINE, MAX_FIELD, INDENT );
  1597.         when RETURN_KEY               =>
  1598.           exit;
  1599.         when others                   =>
  1600.           null;
  1601.       end case;
  1602.     end loop;
  1603.   end PARSE_COMMAND;
  1604.  
  1605.   procedure INITIALIZE_PARSE is 
  1606.   begin
  1607.     CURRENT_MEN   := SEC_DISPLAY_PARAM;
  1608.     CURRENT_COM_FIELD := 2;
  1609.     SET_COM_CURSOR ( HEIGHT_MAX, COM_1_INDENT );
  1610.   end INITIALIZE_PARSE;
  1611.  
  1612.   procedure SET_TEMP ( P1, P2, P3, P4, P5, P6, P7: in COMMAND ) is
  1613.   begin
  1614.     case CURRENT_COM_FIELD is
  1615.       when 1      =>
  1616.         TEMP_COMMAND := P1;
  1617.       when 2      =>
  1618.         TEMP_COMMAND := P2;
  1619.       when 3      =>
  1620.         TEMP_COMMAND := P3;
  1621.       when 4      =>
  1622.         TEMP_COMMAND := P4;
  1623.       when 5      =>
  1624.         TEMP_COMMAND := P5;
  1625.       when 6      =>
  1626.         TEMP_COMMAND := P6;
  1627.       when 7      =>
  1628.         TEMP_COMMAND := P7;
  1629.       when others =>
  1630.         null;
  1631.     end case;
  1632.   end SET_TEMP;
  1633.  
  1634. --  procedure HELP_CHECK is
  1635. --  begin
  1636. --    SET_TEMP ( CONTINUE, LEAVE, QUIT, QUIT, QUIT, QUIT, QUIT );
  1637. --  end HELP_CHECK;
  1638.  
  1639.   function PARSE_COMMAND_LINE return COMMAND is
  1640.   begin
  1641.     TEMP_COMMAND := QUIT;
  1642.     case CURRENT_MEN is
  1643.       when SESSION | SEC_DISPLAY_PARAM | DIAGNOSTIC | PLOTTER_CHAR =>
  1644.         PARSE_COMMAND ( HEIGHT_MAX,     FIELD_4_MAX, COM_1_INDENT );
  1645.         SET_TEMP ( EDIT, SAVE, CONTINUE, LEAVE, QUIT, OPENF, QUIT );
  1646.       when DISPLAY_PARAM =>
  1647.         PARSE_COMMAND ( HEIGHT_MAX,     FIELD_4_MAX, COM_1_INDENT );
  1648.         SET_TEMP ( EDIT, CONTINUE, SAVE, LEAVE, QUIT, OPENF, QUIT);
  1649.       when MAP_OF                                      =>
  1650.         PARSE_COMMAND ( HEIGHT_MAX,     FIELD_5_MAX,   COM_1_INDENT );
  1651.         SET_TEMP ( EDIT, SPECIAL, CONTINUE, LEAVE, QUIT, QUIT, QUIT );
  1652. --      when HELP_TOPIC                                  =>
  1653. --        PARSE_COMMAND ( LEVEL_2_HEIGHT + 5, FIELD_5_MAX,   COM_2_INDENT );
  1654. --        HELP_CHECK;
  1655. --      when HELP_SUBTOPIC                               =>
  1656. --        PARSE_COMMAND ( LEVEL_3_HEIGHT + 7, FIELD_5_MAX,   COM_3_INDENT );
  1657. --        HELP_CHECK;
  1658.       when SPECIAL_DISPLAY                             =>
  1659.         PARSE_COMMAND ( LEVEL_3_HEIGHT + 7, FIELD_1_3_MAX, COM_3_INDENT );
  1660.         SET_TEMP ( EDIT, CONTINUE, LEAVE, QUIT, QUIT, QUIT, QUIT );
  1661.       when others =>
  1662.         null;
  1663.     end case;
  1664.     return TEMP_COMMAND;
  1665.   end PARSE_COMMAND_LINE;
  1666.  
  1667.   procedure SET_SESSION_COM_CURSOR is 
  1668.   begin
  1669.     CURRENT_COM_FIELD := 1;
  1670.     SET_COM_CURSOR ( HEIGHT_MAX, COM_1_INDENT );
  1671.   end SET_SESSION_COM_CURSOR;
  1672.  
  1673.   procedure SET_DP_COM_CURSOR is 
  1674.   begin
  1675.     SET_SESSION_COM_CURSOR;
  1676.   end SET_DP_COM_CURSOR;
  1677.  
  1678.   procedure SET_MAP_COM_CURSOR is 
  1679.   begin
  1680.     SET_SESSION_COM_CURSOR;
  1681.   end SET_MAP_COM_CURSOR;
  1682.  
  1683.   procedure SET_SPECIAL_COM_CURSOR is 
  1684.   begin
  1685.     CURRENT_COM_FIELD := 1;
  1686.     SET_COM_CURSOR ( LEVEL_3_HEIGHT + 7, COM_3_INDENT );
  1687.   end SET_SPECIAL_COM_CURSOR;
  1688.  
  1689. --  procedure SET_HELP_COM_CURSOR is 
  1690. --  begin
  1691. --    CURRENT_COM_FIELD := 1;
  1692. --    SET_COM_CURSOR ( LEVEL_2_HEIGHT + 5, COM_2_INDENT );
  1693. --  end SET_HELP_COM_CURSOR;
  1694.  
  1695. --  procedure SET_HELP_SUB_COM_CURSOR is 
  1696. --  begin
  1697. --    SET_SPECIAL_COM_CURSOR;
  1698. --  end SET_HELP_SUB_COM_CURSOR;
  1699.  
  1700.   function CURRENT_MENU       return MENUS is 
  1701.   begin
  1702.     return CURRENT_MEN;
  1703.   end CURRENT_MENU;
  1704.  
  1705.   procedure SET_LIMIT_RIGHT is
  1706.   begin
  1707.     case CURRENT_TYPE_OF_PROJECTION_LIMIT is
  1708.       when ALL_EARTH                           =>
  1709.         CUR_INDEX := CI29;
  1710.       when MIN_MAX_LAT_LON                     =>
  1711.         CUR_INDEX := CI8;
  1712.       when MIN_MAX_COORDINATES                 =>
  1713.         CUR_INDEX := CI12;
  1714.       when ANGULAR_DIST_FROM_PROJECTION_CENTER =>
  1715.         CUR_INDEX := CI16;
  1716.       when LAT_LON_BOUNDARY                    =>
  1717.         CUR_INDEX := CI20;
  1718.       when others                              =>
  1719.         null;
  1720.       end case;
  1721.   end SET_LIMIT_RIGHT;
  1722.  
  1723.   procedure SET_LIMIT_LEFT is
  1724.   begin
  1725.     case CURRENT_TYPE_OF_PROJECTION_LIMIT is
  1726.       when ALL_EARTH                           =>
  1727.         CUR_INDEX := CI7;
  1728.       when MIN_MAX_LAT_LON                     =>
  1729.         CUR_INDEX := CI11;
  1730.       when MIN_MAX_COORDINATES                 =>
  1731.         CUR_INDEX := CI15;
  1732.       when ANGULAR_DIST_FROM_PROJECTION_CENTER =>
  1733.         CUR_INDEX := CI19;
  1734.       when LAT_LON_BOUNDARY                    =>
  1735.         CUR_INDEX := CI27;
  1736.       when others                              =>
  1737.         null;
  1738.       end case;
  1739.   end SET_LIMIT_LEFT;
  1740.  
  1741.   procedure RIGHT_MOVE is
  1742.   begin
  1743.     case CUR_INDEX is
  1744.       when CI4                 =>
  1745.         if CURRENT_TYPE_OF_PROJECTION = SATELLITE then
  1746.           CUR_INDEX := FIELD_INDEX'succ ( CUR_INDEX );
  1747.         else
  1748.           CUR_INDEX := CI7;
  1749.         end if;
  1750.       when CI7                 =>
  1751.         SET_LIMIT_RIGHT;
  1752.       when CI11 | CI15 | CI19 | CI27 =>
  1753.         CUR_INDEX := CI29;
  1754.       when CI3B =>
  1755.         CUR_INDEX := CI33;
  1756. --      when CI36 =>
  1757.       when CI3C =>
  1758.         CUR_INDEX := CI52;
  1759.       when CI42 =>
  1760.         CUR_INDEX := CI37;
  1761.       when CI45 =>
  1762.         CUR_INDEX := CI43;
  1763.       when CI49 =>
  1764.         CUR_INDEX := CI46;
  1765.       when CI50 | CI51 =>
  1766.         null;
  1767.       when CI52 =>
  1768.         CUR_INDEX := CI0;
  1769.       when others =>
  1770.         CUR_INDEX := FIELD_INDEX'succ ( CUR_INDEX );
  1771.     end case;
  1772.   end RIGHT_MOVE;
  1773.  
  1774.   procedure LEFT_MOVE is
  1775.   begin
  1776.     case CUR_INDEX is
  1777.       when CI0 =>
  1778.         CUR_INDEX := CI52;
  1779.       when CI7                 =>
  1780.         if CURRENT_TYPE_OF_PROJECTION = SATELLITE then
  1781.           CUR_INDEX := FIELD_INDEX'pred ( CUR_INDEX );
  1782.         else
  1783.           CUR_INDEX := CI4;
  1784.         end if;
  1785.       when CI12 | CI16 | CI20 =>
  1786.         CUR_INDEX := CI7;
  1787.       when CI29 =>
  1788.         SET_LIMIT_LEFT;
  1789.       when CI33 =>
  1790.         CUR_INDEX := CI3B;
  1791.       when CI37 =>
  1792.         CUR_INDEX := CI42;
  1793.       when CI43 =>
  1794.         CUR_INDEX := CI45;
  1795.       when CI46 =>
  1796.         CUR_INDEX := CI49;
  1797.       when CI50 | CI51 =>
  1798.         null;
  1799.       when CI52 =>
  1800.         CUR_INDEX := CI3C;
  1801.       when others =>
  1802.         CUR_INDEX := FIELD_INDEX'pred ( CUR_INDEX );
  1803.     end case;
  1804.   end LEFT_MOVE;
  1805.  
  1806.   procedure COLOR_UP ( ITEM : in out COLOR_TYPE ) is
  1807.   begin
  1808.     if ITEM = COLOR_TYPE'first then
  1809.       ITEM := COLOR_TYPE'last;
  1810.     else
  1811.       ITEM := COLOR_TYPE'pred ( ITEM );
  1812.     end if;
  1813.     PUT_STRING ( COLOR_TYPE'image ( ITEM ) & "    " );
  1814.   end COLOR_UP;
  1815.  
  1816.   procedure COLOR_DOWN ( ITEM : in out COLOR_TYPE ) is
  1817.   begin
  1818.     if ITEM = COLOR_TYPE'last then
  1819.       ITEM := COLOR_TYPE'first;
  1820.     else
  1821.       ITEM := COLOR_TYPE'succ ( ITEM );
  1822.     end if;
  1823.     PUT_STRING ( COLOR_TYPE'image ( ITEM ) & "    " );
  1824.   end COLOR_DOWN;
  1825.  
  1826.   procedure BOOL_UP ( ITEM : in out boolean ) is
  1827.   begin
  1828.     ITEM := ( not ITEM );
  1829.     PUT_STRING ( boolean'image ( ITEM ) & "   " );
  1830.   end BOOL_UP;
  1831.  
  1832.   procedure FLOAT_UP ( ITEM : in out float ) is
  1833.   begin
  1834.     ITEM := ITEM + FLOAT_INC;
  1835.     PUT_STRING ( FL_STRING ( ITEM ) );
  1836.   exception
  1837.     when others =>
  1838.       STATUS.ERROR := true;
  1839.       if CURRENT_DIAGS.ERROR then
  1840.         DRAW_ERROR_PORT ( "Error => Invalid numeric item or number too large.",
  1841.                           "  " );
  1842.       end if;
  1843.       PUT_STRING ( FL_STRING ( ITEM ) );
  1844.   end FLOAT_UP;
  1845.  
  1846.   procedure FLOAT_DOWN ( ITEM : in out float ) is
  1847.   begin
  1848.     ITEM := ITEM - FLOAT_INC;
  1849.     PUT_STRING ( FL_STRING ( ITEM ) );
  1850.   exception
  1851.     when others =>
  1852.       STATUS.ERROR := true;
  1853.       if CURRENT_DIAGS.ERROR then
  1854.         DRAW_ERROR_PORT ( "Error => Invalid numeric item or number too small.",
  1855.                           "  " );
  1856.       end if;
  1857.       PUT_STRING ( FL_STRING ( ITEM ) );
  1858.   end FLOAT_DOWN;
  1859.  
  1860.   procedure ARROW_UP is
  1861.   begin
  1862.     POSITION_CURSOR ( X_Y_POS_ALT ( CUR_INDEX ) );
  1863.     case CUR_INDEX is
  1864.       when CI1 =>
  1865.         if CURRENT_TYPE_OF_PROJECTION = KIND_OF_PROJECTION'first then
  1866.           CURRENT_TYPE_OF_PROJECTION := KIND_OF_PROJECTION'last;
  1867.         else
  1868.           CURRENT_TYPE_OF_PROJECTION := KIND_OF_PROJECTION'PRED
  1869.                           ( CURRENT_TYPE_OF_PROJECTION );
  1870.         end if;
  1871.         DRAW_PROJ_PARAM_FIELDS ( OMIT => true );
  1872.       when CI2 =>
  1873.         FLOAT_UP ( CURRENT_PROJECTION.LAT_CENTER );
  1874.       when CI3 =>
  1875.         FLOAT_UP ( CURRENT_PROJECTION.LON_CENTER );
  1876.       when CI4 =>
  1877.         FLOAT_UP ( CURRENT_PROJECTION.CLK_ROT_AR_CENT );
  1878.       when CI5 =>
  1879.         FLOAT_UP ( CURRENT_PROJECTION.SAT_ALTITUDE );
  1880.       when CI6 =>
  1881.         FLOAT_UP ( CURRENT_PROJECTION.VIEW_ALTITUDE );
  1882.       when CI7 =>
  1883.         if CURRENT_TYPE_OF_PROJECTION_LIMIT = KIND_OF_PROJECTION_LIMIT'first then
  1884.           CURRENT_TYPE_OF_PROJECTION_LIMIT := KIND_OF_PROJECTION_LIMIT'last;
  1885.         else
  1886.           CURRENT_TYPE_OF_PROJECTION_LIMIT := KIND_OF_PROJECTION_LIMIT'PRED
  1887.                           ( CURRENT_TYPE_OF_PROJECTION_LIMIT );
  1888.         end if;
  1889.         DRAW_PROJ_LIMIT_FIELDS ( OMIT => true );
  1890.       when CI8  =>
  1891.         FLOAT_UP ( CURRENT_PROJECTION_LIM.MIN_LAT_LON.X );
  1892.       when CI9   =>
  1893.         FLOAT_UP ( CURRENT_PROJECTION_LIM.MIN_LAT_LON.Y );
  1894.       when CI10   =>
  1895.         FLOAT_UP ( CURRENT_PROJECTION_LIM.MAX_LAT_LON.X );
  1896.       when CI11   =>
  1897.         FLOAT_UP ( CURRENT_PROJECTION_LIM.MAX_LAT_LON.Y );
  1898.       when CI12   =>
  1899.         FLOAT_UP ( CURRENT_PROJECTION_LIM.NORTH_EAST.X );
  1900.       when CI13   =>
  1901.         FLOAT_UP ( CURRENT_PROJECTION_LIM.NORTH_EAST.Y );
  1902.       when CI14   =>
  1903.         FLOAT_UP ( CURRENT_PROJECTION_LIM.SOUTH_WEST.X );
  1904.       when CI15   =>
  1905.         FLOAT_UP ( CURRENT_PROJECTION_LIM.SOUTH_WEST.Y );
  1906.       when CI16   =>
  1907.         FLOAT_UP ( CURRENT_PROJECTION_LIM.ANGLE_UP );
  1908.       when CI17   =>
  1909.         FLOAT_UP ( CURRENT_PROJECTION_LIM.ANGLE_DOWN );
  1910.       when CI18   =>
  1911.         FLOAT_UP ( CURRENT_PROJECTION_LIM.ANGLE_RIGHT );
  1912.       when CI19   =>
  1913.         FLOAT_UP ( CURRENT_PROJECTION_LIM.ANGLE_LEFT );
  1914.       when CI20   =>
  1915.         FLOAT_UP ( CURRENT_PROJECTION_LIM.POINT_UP.X );
  1916.       when CI21   =>
  1917.         FLOAT_UP ( CURRENT_PROJECTION_LIM.POINT_UP.Y );
  1918.       when CI22   =>
  1919.         FLOAT_UP ( CURRENT_PROJECTION_LIM.POINT_DOWN.X );
  1920.       when CI23   =>
  1921.         FLOAT_UP ( CURRENT_PROJECTION_LIM.POINT_DOWN.Y );
  1922.       when CI24   =>
  1923.         FLOAT_UP ( CURRENT_PROJECTION_LIM.POINT_RIGHT.X );
  1924.       when CI25   =>
  1925.         FLOAT_UP ( CURRENT_PROJECTION_LIM.POINT_RIGHT.Y );
  1926.       when CI26   =>
  1927.         FLOAT_UP ( CURRENT_PROJECTION_LIM.POINT_LEFT.X );
  1928.       when CI27   =>
  1929.         FLOAT_UP ( CURRENT_PROJECTION_LIM.POINT_LEFT.Y );
  1930.       when CI29 =>
  1931.         COLOR_UP ( CURRENT_COLOR.MAP_OUTLINE );
  1932.       when CI30 =>
  1933.         COLOR_UP ( CURRENT_COLOR.GRID_LINES );
  1934.       when CI31 =>
  1935.         COLOR_UP ( CURRENT_COLOR.HORIZON );
  1936.       when CI3A =>
  1937.         COLOR_UP ( CURRENT_COLOR.DEFAULT );
  1938.       when CI3B =>
  1939.         COLOR_UP ( CURRENT_COLOR.BACKGROUND );
  1940.       when CI33 =>
  1941.         BOOL_UP ( CURRENT_GRID_LINES.SHOW_LINES );
  1942.       when CI34 =>
  1943.         FLOAT_UP ( CURRENT_GRID_LINES.DEGREES_BTWN_LATS );
  1944.       when CI35 =>
  1945.         FLOAT_UP ( CURRENT_GRID_LINES.DEGREES_BTWN_LONS );
  1946.       when CI3C =>
  1947.         FLOAT_UP ( CURRENT_GRID_LINES.SEGMENT_LENGTH );
  1948. --      when CI36 =>
  1949. --        BOOL_UP ( CURRENT_CLIPPING );
  1950.       when CI40 =>
  1951.         COLOR_UP ( CURRENT_SPECIALS.BEAM_COLOR );
  1952.       when CI41 =>
  1953.         COLOR_UP ( CURRENT_SPECIALS.SWATH_COLOR );
  1954.       when CI42 =>
  1955.         COLOR_UP ( CURRENT_SPECIALS.POINTS_COLOR );
  1956.         CURRENT_COLOR.MAP_OUTLINE := CURRENT_SPECIALS.POINTS_COLOR;
  1957.       when CI43 =>
  1958.         BOOL_UP ( CURRENT_DIAGS.WARNING );
  1959.       when CI44 =>
  1960.         BOOL_UP ( CURRENT_DIAGS.ERROR );
  1961.       when CI45 =>
  1962.         BOOL_UP ( CURRENT_DIAGS.FATAL );
  1963.       when CI46 =>
  1964.         FLOAT_UP ( CURRENT_PLOT_CHARACTERISTICS.AXIS_LENGTH.X );
  1965.       when CI47 =>
  1966.         FLOAT_UP ( CURRENT_PLOT_CHARACTERISTICS.AXIS_LENGTH.Y );
  1967.       when CI48 =>
  1968.         FLOAT_UP ( CURRENT_PLOT_CHARACTERISTICS.ORIGIN.X );
  1969.       when CI49 =>
  1970.         FLOAT_UP ( CURRENT_PLOT_CHARACTERISTICS.ORIGIN.Y );
  1971.       when CI52 =>
  1972.         BOOL_UP ( CURRENT_LAND );
  1973.       when others =>
  1974.         null;
  1975.       end case;
  1976.   end ARROW_UP;
  1977.  
  1978.   procedure ARROW_DOWN is
  1979.   begin
  1980.     POSITION_CURSOR ( X_Y_POS_ALT ( CUR_INDEX ) );
  1981.     case CUR_INDEX is
  1982.       when CI1 =>
  1983.         if CURRENT_TYPE_OF_PROJECTION = KIND_OF_PROJECTION'last then
  1984.           CURRENT_TYPE_OF_PROJECTION := KIND_OF_PROJECTION'first;
  1985.         else
  1986.           CURRENT_TYPE_OF_PROJECTION := KIND_OF_PROJECTION'succ
  1987.                           ( CURRENT_TYPE_OF_PROJECTION );
  1988.         end if;
  1989.         DRAW_PROJ_PARAM_FIELDS ( OMIT => true );
  1990.       when CI2 =>
  1991.         FLOAT_DOWN ( CURRENT_PROJECTION.LAT_CENTER );
  1992.       when CI3 =>
  1993.         FLOAT_DOWN ( CURRENT_PROJECTION.LON_CENTER );
  1994.       when CI4 =>
  1995.         FLOAT_DOWN ( CURRENT_PROJECTION.CLK_ROT_AR_CENT );
  1996.       when CI5 =>
  1997.         FLOAT_DOWN ( CURRENT_PROJECTION.SAT_ALTITUDE );
  1998.       when CI6 =>
  1999.         FLOAT_DOWN ( CURRENT_PROJECTION.VIEW_ALTITUDE );
  2000.       when CI7 =>
  2001.         if CURRENT_TYPE_OF_PROJECTION_LIMIT = KIND_OF_PROJECTION_LIMIT'last then
  2002.           CURRENT_TYPE_OF_PROJECTION_LIMIT := KIND_OF_PROJECTION_LIMIT'first;
  2003.         else
  2004.           CURRENT_TYPE_OF_PROJECTION_LIMIT := KIND_OF_PROJECTION_LIMIT'succ
  2005.                           ( CURRENT_TYPE_OF_PROJECTION_LIMIT );
  2006.         end if;
  2007.         DRAW_PROJ_LIMIT_FIELDS ( OMIT => true );
  2008.       when CI8  =>
  2009.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.MIN_LAT_LON.X );
  2010.       when CI9   =>
  2011.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.MIN_LAT_LON.Y );
  2012.       when CI10   =>
  2013.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.MAX_LAT_LON.X );
  2014.       when CI11   =>
  2015.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.MAX_LAT_LON.Y );
  2016.       when CI12   =>
  2017.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.NORTH_EAST.X );
  2018.       when CI13   =>
  2019.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.NORTH_EAST.Y );
  2020.       when CI14   =>
  2021.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.SOUTH_WEST.X );
  2022.       when CI15   =>
  2023.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.SOUTH_WEST.Y );
  2024.       when CI16   =>
  2025.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.ANGLE_UP );
  2026.       when CI17   =>
  2027.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.ANGLE_DOWN );
  2028.       when CI18   =>
  2029.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.ANGLE_RIGHT );
  2030.       when CI19   =>
  2031.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.ANGLE_LEFT );
  2032.       when CI20   =>
  2033.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.POINT_UP.X );
  2034.       when CI21   =>
  2035.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.POINT_UP.Y );
  2036.       when CI22   =>
  2037.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.POINT_DOWN.X );
  2038.       when CI23   =>
  2039.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.POINT_DOWN.Y );
  2040.       when CI24   =>
  2041.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.POINT_RIGHT.X );
  2042.       when CI25   =>
  2043.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.POINT_RIGHT.Y );
  2044.       when CI26   =>
  2045.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.POINT_LEFT.X );
  2046.       when CI27   =>
  2047.         FLOAT_DOWN ( CURRENT_PROJECTION_LIM.POINT_LEFT.Y );
  2048.       when CI29 =>
  2049.         COLOR_DOWN ( CURRENT_COLOR.MAP_OUTLINE );
  2050.       when CI30 =>
  2051.         COLOR_DOWN ( CURRENT_COLOR.GRID_LINES );
  2052.       when CI31 =>
  2053.         COLOR_DOWN ( CURRENT_COLOR.HORIZON );
  2054.       when CI3A =>
  2055.         COLOR_DOWN ( CURRENT_COLOR.DEFAULT );
  2056.       when CI3B =>
  2057.         COLOR_DOWN ( CURRENT_COLOR.BACKGROUND );
  2058.       when CI33 =>
  2059.         BOOL_UP ( CURRENT_GRID_LINES.SHOW_LINES );
  2060.       when CI34 =>
  2061.         FLOAT_DOWN ( CURRENT_GRID_LINES.DEGREES_BTWN_LATS );
  2062.       when CI35 =>
  2063.         FLOAT_DOWN ( CURRENT_GRID_LINES.DEGREES_BTWN_LONS );
  2064.       when CI3C =>
  2065.         FLOAT_DOWN ( CURRENT_GRID_LINES.SEGMENT_LENGTH );
  2066. --      when CI36 =>
  2067. --        BOOL_UP ( CURRENT_CLIPPING );
  2068.       when CI40 =>
  2069.         COLOR_DOWN ( CURRENT_SPECIALS.BEAM_COLOR );
  2070.       when CI41 =>
  2071.         COLOR_DOWN ( CURRENT_SPECIALS.SWATH_COLOR );
  2072.       when CI42 =>
  2073.         COLOR_DOWN ( CURRENT_SPECIALS.POINTS_COLOR );
  2074.         CURRENT_COLOR.MAP_OUTLINE := CURRENT_SPECIALS.POINTS_COLOR;
  2075.       when CI43 =>
  2076.         BOOL_UP ( CURRENT_DIAGS.WARNING );
  2077.       when CI44 =>
  2078.         BOOL_UP ( CURRENT_DIAGS.ERROR );
  2079.       when CI45 =>
  2080.         BOOL_UP ( CURRENT_DIAGS.FATAL );
  2081.       when CI46 =>
  2082.         FLOAT_DOWN ( CURRENT_PLOT_CHARACTERISTICS.AXIS_LENGTH.X );
  2083.       when CI47 =>
  2084.         FLOAT_DOWN ( CURRENT_PLOT_CHARACTERISTICS.AXIS_LENGTH.Y );
  2085.       when CI48 =>
  2086.         FLOAT_DOWN ( CURRENT_PLOT_CHARACTERISTICS.ORIGIN.X );
  2087.       when CI49 =>
  2088.         FLOAT_DOWN ( CURRENT_PLOT_CHARACTERISTICS.ORIGIN.Y );
  2089.       when CI52 =>
  2090.         BOOL_UP ( CURRENT_LAND );
  2091.       when others =>
  2092.         null;
  2093.       end case;
  2094.   end ARROW_DOWN;
  2095.  
  2096.   procedure FILLER is
  2097.   begin
  2098.     case CUR_INDEX is
  2099.       when CI0 | CI37 .. CI39 | CI50 | CI51 =>
  2100.         FILL ( 40 );
  2101.       when CI1 =>
  2102.         FILL ( 15 );
  2103.       when CI7 =>
  2104.         FILL ( 35 );
  2105.       when CI2 .. CI6 | CI8 .. CI27 | CI34 .. CI3C | CI46 .. CI49 =>
  2106.         FILL ( 12 );
  2107.       when CI28 .. CI33 | CI40 .. CI45 | CI52 =>
  2108.         FILL ( 5 );
  2109.       when others =>
  2110.         null;
  2111.       end case;
  2112.   end FILLER;
  2113.  
  2114.   procedure FLUSH_BOOL ( ITEM : out boolean ) is
  2115.   begin
  2116.     HOLD_STRING ( 1 .. 5 ) := ( 1 .. 5 => ' ' );
  2117.     LAST         := 0;
  2118.     FLUSH ( HOLD_STRING ( 1 .. 5 ), LAST );
  2119.     if LAST /= 0 then
  2120.       ITEM := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  2121.     end if;
  2122.   exception
  2123.     when others =>
  2124.       STATUS.ERROR := true;
  2125.       if CURRENT_DIAGS.ERROR then
  2126.         DRAW_ERROR_PORT ( "Error => Invalid boolean value.", "  " );
  2127.       end if;
  2128.   end FLUSH_BOOL;
  2129.  
  2130.   procedure FLUSH_COLOR ( ITEM : out COLOR_TYPE ) is
  2131.   begin
  2132.     HOLD_STRING ( 1 .. 5 ) := ( 1 .. 5 => ' ' );
  2133.     LAST         := 0;
  2134.     FLUSH ( HOLD_STRING ( 1 .. 5 ), last );
  2135.     if LAST /= 0 then
  2136.       ITEM := COLOR_TYPE'value ( HOLD_STRING ( 1 .. last ) );
  2137.     end if;
  2138.   exception
  2139.     when others =>
  2140.       STATUS.ERROR := true;
  2141.       if CURRENT_DIAGS.ERROR then
  2142.         DRAW_ERROR_PORT ( "Error => Invalid color value.", "  " );
  2143.       end if;
  2144.   end FLUSH_COLOR;
  2145.  
  2146.   procedure FLUSH_FLOAT ( ITEM : out float ) is
  2147.   begin
  2148.     HOLD_STRING ( 1 .. 12 ) := ( 1 .. 12 => ' ' );
  2149.     LAST         := 0;
  2150.     FLUSH ( HOLD_STRING ( 1 .. 12 ), last );
  2151.     if LAST /= 0 then
  2152.       ITEM := STRING_FL ( HOLD_STRING ( 1 .. 12 ) );
  2153.     end if;
  2154.   exception
  2155.     when others =>
  2156.       STATUS.ERROR := true;
  2157.       if CURRENT_DIAGS.ERROR then
  2158.         DRAW_ERROR_PORT ( "Error => Invalid numeric value or number too large.",
  2159.                           "  " );
  2160.       end if;
  2161.   end FLUSH_FLOAT;
  2162.  
  2163.   procedure FLUSHER is
  2164.   begin
  2165.     HOLD_STRING := ( 1 .. 40 => ' ' );
  2166.     LAST        := 0;
  2167.     case CUR_INDEX is
  2168.       when CI0 =>
  2169.         FLUSH ( HOLD_STRING , last );
  2170.         if LAST /= 0 then
  2171.           CURRENT_MAP_TITLE := HOLD_STRING;
  2172.         end if;
  2173.       when CI1 =>
  2174.         FLUSH ( HOLD_STRING ( 1 .. 15 ), last );
  2175.         if LAST /= 0 then
  2176.           CURRENT_TYPE_OF_PROJECTION := KIND_OF_PROJECTION'value 
  2177.             ( HOLD_STRING ( 1 .. last ) );
  2178.         DRAW_PROJ_PARAM_FIELDS ( OMIT => true );
  2179.         end if;
  2180.       when CI2 =>
  2181.         FLUSH_FLOAT ( CURRENT_PROJECTION.LAT_CENTER );
  2182.       when CI3 =>
  2183.         FLUSH_FLOAT ( CURRENT_PROJECTION.LON_CENTER );
  2184.       when CI4 =>
  2185.         FLUSH_FLOAT ( CURRENT_PROJECTION.CLK_ROT_AR_CENT );
  2186.       when CI5 =>
  2187.         FLUSH_FLOAT ( CURRENT_PROJECTION.SAT_ALTITUDE );
  2188.       when CI6 =>
  2189.         FLUSH_FLOAT ( CURRENT_PROJECTION.VIEW_ALTITUDE );
  2190.       when CI7 =>
  2191.         FLUSH ( HOLD_STRING ( 1 .. 35 ), last  );
  2192.         if LAST /= 0 then
  2193.           CURRENT_TYPE_OF_PROJECTION_LIMIT := KIND_OF_PROJECTION_LIMIT'value 
  2194.             ( HOLD_STRING ( 1 .. last ) );
  2195.         DRAW_PROJ_LIMIT_FIELDS ( OMIT => true );
  2196.         end if;
  2197.       when CI8  =>
  2198.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.MIN_LAT_LON.X );
  2199.       when CI9   =>
  2200.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.MIN_LAT_LON.Y );
  2201.       when CI10   =>
  2202.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.MAX_LAT_LON.X );
  2203.       when CI11   =>
  2204.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.MAX_LAT_LON.Y );
  2205.       when CI12   =>
  2206.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.NORTH_EAST.X );
  2207.       when CI13   =>
  2208.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.NORTH_EAST.Y );
  2209.       when CI14   =>
  2210.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.SOUTH_WEST.X );
  2211.       when CI15   =>
  2212.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.SOUTH_WEST.Y );
  2213.       when CI16   =>
  2214.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.ANGLE_UP );
  2215.       when CI17   =>
  2216.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.ANGLE_DOWN );
  2217.       when CI18   =>
  2218.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.ANGLE_RIGHT );
  2219.       when CI19   =>
  2220.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.ANGLE_LEFT );
  2221.       when CI20   =>
  2222.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.POINT_UP.X );
  2223.       when CI21   =>
  2224.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.POINT_UP.Y );
  2225.       when CI22   =>
  2226.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.POINT_DOWN.X );
  2227.       when CI23   =>
  2228.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.POINT_DOWN.Y );
  2229.       when CI24   =>
  2230.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.POINT_RIGHT.X );
  2231.       when CI25   =>
  2232.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.POINT_RIGHT.Y );
  2233.       when CI26   =>
  2234.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.POINT_LEFT.X );
  2235.       when CI27   =>
  2236.         FLUSH_FLOAT ( CURRENT_PROJECTION_LIM.POINT_LEFT.Y );
  2237.       when CI29 =>
  2238.         FLUSH_COLOR ( CURRENT_COLOR.MAP_OUTLINE );
  2239.       when CI30 =>
  2240.         FLUSH_COLOR ( CURRENT_COLOR.GRID_LINES );
  2241.       when CI31 =>
  2242.         FLUSH_COLOR ( CURRENT_COLOR.HORIZON );
  2243.       when CI3A =>
  2244.         FLUSH_COLOR ( CURRENT_COLOR.DEFAULT );
  2245.       when CI3B =>
  2246.         FLUSH_COLOR ( CURRENT_COLOR.BACKGROUND );
  2247.       when CI33 =>
  2248.         FLUSH_BOOL ( CURRENT_GRID_LINES.SHOW_LINES );
  2249.       when CI34 =>
  2250.         FLUSH_FLOAT ( CURRENT_GRID_LINES.DEGREES_BTWN_LATS );
  2251.       when CI35 =>
  2252.         FLUSH_FLOAT ( CURRENT_GRID_LINES.DEGREES_BTWN_LONS );
  2253.       when CI3C =>
  2254.         FLUSH_FLOAT ( CURRENT_GRID_LINES.SEGMENT_LENGTH );
  2255. --      when CI36 =>
  2256. --        FLUSH_BOOL ( CURRENT_CLIPPING );
  2257.       when CI37 =>
  2258.         FLUSH ( HOLD_STRING, LAST );
  2259.         if LAST /= 0 then
  2260.           CURRENT_SPECIALS.BEAM_DATA := HOLD_STRING;
  2261.           if CURRENT_SPECIALS.BEAM_DATA = BLANK_STRING then
  2262.             LAST := 0;
  2263.           end if;
  2264.         CURRENT_SPECIALS.BEAM_LAST := LAST;
  2265.         end if;
  2266.       when CI38 =>
  2267.         FLUSH ( HOLD_STRING, LAST );
  2268.         if LAST /= 0 then
  2269.           CURRENT_SPECIALS.SWATH_DATA := HOLD_STRING;
  2270.           if CURRENT_SPECIALS.SWATH_DATA = BLANK_STRING then
  2271.             LAST := 0;
  2272.           end if;
  2273.         CURRENT_SPECIALS.SWATH_LAST := LAST;
  2274.         end if;
  2275.       when CI39 =>
  2276.         FLUSH ( HOLD_STRING, LAST );
  2277.         if LAST /= 0 then
  2278.           CURRENT_SPECIALS.POINTS_DATA := HOLD_STRING;
  2279.           if CURRENT_SPECIALS.POINTS_DATA = BLANK_STRING then
  2280.             LAST := 0;
  2281.           end if;
  2282.         CURRENT_SPECIALS.POINTS_LAST := LAST;
  2283.         end if;
  2284.       when CI40 =>
  2285.         FLUSH_COLOR ( CURRENT_SPECIALS.BEAM_COLOR );
  2286.       when CI41 =>
  2287.         FLUSH_COLOR ( CURRENT_SPECIALS.SWATH_COLOR );
  2288.       when CI42 =>
  2289.         FLUSH_COLOR ( CURRENT_SPECIALS.POINTS_COLOR );
  2290.         CURRENT_COLOR.MAP_OUTLINE := CURRENT_SPECIALS.POINTS_COLOR;
  2291.       when CI43 =>
  2292.         FLUSH_BOOL ( CURRENT_DIAGS.WARNING );
  2293.       when CI44 =>
  2294.         FLUSH_BOOL ( CURRENT_DIAGS.ERROR );
  2295.       when CI45 =>
  2296.         FLUSH_BOOL ( CURRENT_DIAGS.FATAL );
  2297.       when CI46 =>
  2298.         FLUSH_FLOAT ( CURRENT_PLOT_CHARACTERISTICS.AXIS_LENGTH.X );
  2299.       when CI47 =>
  2300.         FLUSH_FLOAT ( CURRENT_PLOT_CHARACTERISTICS.AXIS_LENGTH.Y );
  2301.       when CI48 =>
  2302.         FLUSH_FLOAT ( CURRENT_PLOT_CHARACTERISTICS.ORIGIN.X );
  2303.       when CI49 =>
  2304.         FLUSH_FLOAT ( CURRENT_PLOT_CHARACTERISTICS.ORIGIN.Y );
  2305.       when CI50 =>
  2306.         FLUSH ( HOLD_STRING, LAST );
  2307.         CURRENT_SESSION_FILENAME := HOLD_STRING;
  2308.       when CI51 =>
  2309.         FLUSH ( HOLD_STRING, LAST );
  2310.         CURRENT_DISPLAY_FILENAME := HOLD_STRING;
  2311.       when CI52 =>
  2312.         FLUSH_BOOL ( CURRENT_LAND );
  2313.       when others =>
  2314.         null;
  2315.       end case;
  2316.   exception 
  2317.     when others =>
  2318.       STATUS.ERROR := true;
  2319.       if CURRENT_DIAGS.ERROR then
  2320.         DRAW_ERROR_PORT ( 
  2321.          "Error => Invalid kind of projection or projection limit.", "  " );
  2322.       end if;
  2323.   end FLUSHER;
  2324.  
  2325.   procedure PARSE_LOOP is
  2326.     POS : boolean := true;
  2327.   begin
  2328.     loop
  2329.       if POS then
  2330.         POSITION_CURSOR ( X_Y_POS_ALT ( CUR_INDEX ) );
  2331.       else
  2332.         POS := true;
  2333.       end if;
  2334.       CURRENT_TOKEN := PARSE_INPUT;
  2335.       case CURRENT_TOKEN is
  2336.         when RIGHT_ARROW =>
  2337.           FLUSHER;
  2338.           exit when ( CUR_INDEX = CI50 or else CUR_INDEX = CI51 );
  2339.           RIGHT_MOVE;
  2340.         when LEFT_ARROW =>
  2341.           FLUSHER;
  2342.           exit when ( CUR_INDEX = CI50 or else CUR_INDEX = CI51 );
  2343.           LEFT_MOVE;
  2344.         when TAB                     =>
  2345.           FLUSHER;
  2346.           exit;
  2347.         when UP_ARROW                =>
  2348.           FLUSHER;
  2349.           exit when ( CUR_INDEX = CI50 or else CUR_INDEX = CI51 );
  2350.           ARROW_UP;
  2351.         when DOWN_ARROW              =>
  2352.           FLUSHER;
  2353.           exit when ( CUR_INDEX = CI50 or else CUR_INDEX = CI51 );
  2354.           ARROW_DOWN;
  2355.         when ALPHA_NUM | BACK_SPACE | RETURN_KEY =>
  2356.           POS := false;
  2357.           FILLER;
  2358.         when others                  =>
  2359.           null;
  2360.       end case;
  2361.     end loop;
  2362.   end PARSE_LOOP;
  2363.  
  2364.   procedure EDIT_DISPLAY is
  2365.   begin
  2366.     CUR_INDEX := CI0;
  2367.     PARSE_LOOP;
  2368.   end EDIT_DISPLAY;
  2369.  
  2370.   procedure EDIT_SPECIALS is
  2371.   begin
  2372.     CUR_INDEX := CI37;
  2373.     PARSE_LOOP;
  2374.   end EDIT_SPECIALS;
  2375.  
  2376.   procedure EDIT_DIAGNOSTICS is
  2377.   begin
  2378.     CUR_INDEX := CI43;
  2379.     PARSE_LOOP;
  2380.   end EDIT_DIAGNOSTICS;
  2381.  
  2382.   procedure EDIT_PLOT is
  2383.   begin
  2384.     CUR_INDEX := CI46;
  2385.     PARSE_LOOP;
  2386.   end EDIT_PLOT;
  2387.  
  2388.   procedure EDIT is 
  2389.   begin
  2390.     case CURRENT_MEN is
  2391.       when SESSION | SEC_DISPLAY_PARAM | DIAGNOSTIC | PLOTTER_CHAR =>
  2392.         CURRENT_MEN := SEC_DISPLAY_PARAM;
  2393.         EDIT_DISPLAY;
  2394.         CURRENT_MEN := SPECIAL_DISPLAY;
  2395.         DRAW_SDF_MENU ( false );
  2396.         EDIT_SPECIALS;
  2397.         CURRENT_MEN := DIAGNOSTIC;
  2398.         DRAW_DIG_MENU;
  2399.         EDIT_DIAGNOSTICS;
  2400.         CURRENT_MEN := PLOTTER_CHAR;
  2401.         DRAW_PLC_MENU;
  2402.         EDIT_PLOT;
  2403.         SET_DEFAULTS_FROM_CURRENTS;
  2404.         DRAW_DP_MENU ( TWO );
  2405.         SET_SESSION_COM_CURSOR;
  2406.       when DISPLAY_PARAM =>
  2407.         EDIT_DISPLAY;
  2408.         SET_SESSION_COM_CURSOR;
  2409.       when SPECIAL_DISPLAY =>
  2410.         EDIT_SPECIALS;
  2411.         SET_SPECIAL_COM_CURSOR;
  2412.       when MAP_OF =>
  2413.         CURRENT_MEN := DISPLAY_PARAM;
  2414.         DRAW_DP_MENU ( ONE );
  2415.         SET_DP_COM_CURSOR;
  2416.         EDIT_DISPLAY;
  2417.         SET_SESSION_COM_CURSOR;
  2418.       when others =>
  2419.         null;
  2420.     end case;
  2421.   end EDIT;
  2422.  
  2423.   procedure CONTINUE is 
  2424.   begin
  2425.     case CURRENT_MEN is
  2426.       when SESSION | SEC_DISPLAY_PARAM | DIAGNOSTIC | PLOTTER_CHAR =>
  2427.         CURRENT_MEN := DISPLAY_PARAM;
  2428.         DRAW_DP_MENU ( ONE );
  2429.         SET_DP_COM_CURSOR;
  2430.       when DISPLAY_PARAM =>
  2431.         CURRENT_MEN := MAP_OF;
  2432.         DRAW_MAP_MENU;
  2433.         DRAW_MAP := true;
  2434.         SET_MAP_COM_CURSOR;
  2435.       when MAP_OF =>
  2436.         CURRENT_MEN := DISPLAY_PARAM;
  2437.         DRAW_DP_MENU ( ONE );
  2438.         SET_DP_COM_CURSOR;
  2439.       when SPECIAL_DISPLAY =>
  2440.         CURRENT_MEN := MAP_OF;
  2441.         DRAW_MAP_MENU;
  2442.         DRAW_MAP := true;
  2443.         SET_MAP_COM_CURSOR;
  2444. --      when HELP_TOPIC =>
  2445. --        null;
  2446. --      when HELP_SUBTOPIC =>
  2447. --        null;
  2448.       when others =>
  2449.         null;
  2450.     end case;
  2451.   end CONTINUE;
  2452.  
  2453.   procedure SAVE is 
  2454.   begin
  2455.     case CURRENT_MEN is
  2456.       when SESSION | SEC_DISPLAY_PARAM | DIAGNOSTIC | PLOTTER_CHAR =>
  2457.         DRAW_SESSION_FILENAME;
  2458.         CUR_INDEX := CI50;
  2459.         PARSE_LOOP;
  2460.         if CURRENT_SESSION_FILENAME /= BLANK_STRING then
  2461.           CREATE_MENU_FILE ( CURRENT_SESSION_FILENAME ( 1 .. LAST ) );
  2462.           WRITE_SESSION_CURRENTS;
  2463.           CLOSE_MENU_FILE;
  2464.         end if;
  2465.         SET_SESSION_COM_CURSOR;
  2466.       when DISPLAY_PARAM                            =>
  2467.         DRAW_DISPLAY_FILENAME;
  2468.         CUR_INDEX := CI51;
  2469.         PARSE_LOOP;
  2470.         if CURRENT_DISPLAY_FILENAME /= BLANK_STRING then
  2471.           CREATE_MENU_FILE ( CURRENT_DISPLAY_FILENAME ( 1 .. LAST ) );
  2472.           WRITE_SESSION_CURRENTS;
  2473.           CLOSE_MENU_FILE;
  2474.         end if;
  2475.         SET_SESSION_COM_CURSOR;
  2476.       when others                                   =>
  2477.         null;
  2478.     end case;
  2479.   exception
  2480.     when others =>
  2481.       STATUS.ERROR := true;
  2482.       if CURRENT_DIAGS.ERROR then
  2483.         DRAW_ERROR_PORT ( "Error => Invalid file name.", "  " );
  2484.       end if;
  2485.       SET_SESSION_COM_CURSOR;
  2486.   end SAVE;
  2487.  
  2488. --  procedure HELP is 
  2489. --  begin
  2490. --    case CURRENT_MEN is
  2491. --      when SESSION | SEC_DISPLAY_PARAM | DIAGNOSTIC | PLOTTER_CHAR =>
  2492. --        null;
  2493. --      when DISPLAY_PARAM                            =>
  2494. --        null;
  2495. --      when MAP_OF                                   =>
  2496. --        null;
  2497. --      when SPECIAL_DISPLAY                          =>
  2498. --        null;
  2499. --      when others                                   =>
  2500. --        null;
  2501. --    end case;
  2502. --  end HELP;
  2503.  
  2504.   procedure LEAVE is 
  2505.   begin
  2506.     case CURRENT_MEN is
  2507.       when SESSION | SEC_DISPLAY_PARAM | DIAGNOSTIC | PLOTTER_CHAR =>
  2508.         SESSION_TERMINATED := TRUE;
  2509.         DRAW_MAP := TRUE;        
  2510.       when DISPLAY_PARAM                            =>
  2511.         SET_CURRENTS_FROM_DEFAULTS;
  2512.         CURRENT_MEN := SESSION;
  2513.         DRAW_SESSION_MENU;
  2514.         DRAW_DP_MENU ( TWO );
  2515.         SET_SESSION_COM_CURSOR;
  2516.       when MAP_OF                                   =>
  2517.         CURRENT_MEN := DISPLAY_PARAM;
  2518.         DRAW_DP_MENU ( ONE );
  2519.         SET_DP_COM_CURSOR;
  2520.       when SPECIAL_DISPLAY                          =>
  2521.         DRAW_MAP := TRUE;
  2522.         CURRENT_MEN := MAP_OF;
  2523.         DRAW_MAP_MENU;
  2524.         SET_MAP_COM_CURSOR;
  2525. --      when HELP_TOPIC                               =>
  2526. --        null;
  2527. --      when HELP_SUBTOPIC                            =>
  2528. --        null;
  2529.       when others                                   =>
  2530.         null;
  2531.     end case;
  2532.   end LEAVE;
  2533.  
  2534.   procedure QUIT is 
  2535.   begin
  2536.     DRAW_MAP := TRUE;
  2537.     SESSION_TERMINATED := TRUE;
  2538.   end;
  2539.  
  2540. --  procedure UNDO is 
  2541. --  begin
  2542. --    null;
  2543. --  end;
  2544.  
  2545.   procedure SPECIAL is 
  2546.   begin
  2547.     CURRENT_MEN := SPECIAL_DISPLAY;
  2548.     DRAW_SDF_MENU;
  2549.     SET_SPECIAL_COM_CURSOR;
  2550.   end;
  2551.  
  2552. --  procedure APPEND is
  2553. --  begin
  2554. --    null;
  2555. --  end;
  2556.  
  2557.   procedure OPENF is
  2558.   begin
  2559.     case CURRENT_MEN is
  2560.       when SESSION | SEC_DISPLAY_PARAM | DIAGNOSTIC | PLOTTER_CHAR =>
  2561.         DRAW_SESSION_FILENAME;
  2562.         CUR_INDEX := CI50;
  2563.         PARSE_LOOP;
  2564.         if CURRENT_SESSION_FILENAME /= BLANK_STRING then
  2565.           OPEN_MENU_FILE ( CURRENT_SESSION_FILENAME ( 1 .. LAST ) );
  2566.           READ_SESSION_DEFAULTS;
  2567.           CLOSE_MENU_FILE;
  2568.         end if;
  2569.         CURRENT_MEN := DISPLAY_PARAM;
  2570.         LEAVE;
  2571.       when DISPLAY_PARAM                            =>
  2572.         DRAW_DISPLAY_FILENAME;
  2573.         CUR_INDEX := CI51;
  2574.         PARSE_LOOP;
  2575.         if CURRENT_DISPLAY_FILENAME /= BLANK_STRING then
  2576.           OPEN_MENU_FILE ( CURRENT_DISPLAY_FILENAME ( 1 .. LAST ) );
  2577.           READ_DISPLAY_DEFAULTS;
  2578.           CLOSE_MENU_FILE;
  2579.         end if;
  2580.         CURRENT_MEN := MAP_OF;
  2581.         SET_CURRENTS_FROM_DEFAULTS;
  2582.         LEAVE;
  2583.       when others                                   =>
  2584.         null;
  2585.     end case;
  2586.   exception
  2587.     when CONSTRAINT_ERROR =>
  2588.       CLOSE_MENU_FILE;
  2589.       STATUS.ERROR := true;
  2590.       if CURRENT_DIAGS.ERROR then
  2591.         DRAW_ERROR_PORT ( "Error => Invalid file data for this menu.", "  " );
  2592.       end if;
  2593.       SET_SESSION_COM_CURSOR;
  2594.     when others =>
  2595.       STATUS.ERROR := true;
  2596.       if CURRENT_DIAGS.ERROR then
  2597.         DRAW_ERROR_PORT ( "Error => File not found.", "  " );
  2598.       end if;
  2599.       SET_SESSION_COM_CURSOR;
  2600.   end OPENF;
  2601.  
  2602. begin
  2603.   null;
  2604. end MENU_PARSE;
  2605. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2606. --menufilei.txt
  2607. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2608. with TEXT_IO, MENU_CURRENTS, MENU_TYPES, GRAPHIC;
  2609. package body MENU_FILE_IO is
  2610.  
  2611.   use TEXT_IO;
  2612.   package FLT_IO is new FLOAT_IO ( float );
  2613.   use FLT_IO;
  2614.   use MENU_CURRENTS, MENU_TYPES, GRAPHIC;
  2615.  
  2616.   CURRENT_FILE      :      FILE_TYPE;
  2617.  
  2618.   HOLD_STRING       :      string ( 1 .. 40 ) := ( 1 .. 40 => ' ' );
  2619.   LAST              :      integer := 0;
  2620.  
  2621.   procedure OPEN_MENU_FILE   ( FILE : in string ) is -- use for OPENF command.
  2622.   begin
  2623.     OPEN ( CURRENT_FILE, IN_FILE, FILE ( FILE'first .. FILE'last ) );
  2624.   end OPEN_MENU_FILE;
  2625.  
  2626.   procedure CLOSE_MENU_FILE is -- use for OPENF & SAVE commands.
  2627.   begin
  2628.     CLOSE ( CURRENT_FILE );
  2629.   end CLOSE_MENU_FILE;
  2630.  
  2631.   procedure CREATE_MENU_FILE ( FILE : in string ) is -- use for SAVE command.
  2632.   begin
  2633.     CREATE ( CURRENT_FILE, OUT_FILE, FILE ( FILE'first .. FILE'last ) );
  2634.   end CREATE_MENU_FILE;  
  2635.  
  2636.   procedure READ             ( ITEM : in out float  ) is
  2637.   begin
  2638.     GET ( CURRENT_FILE, ITEM );
  2639.     SKIP_LINE ( CURRENT_FILE );
  2640.   end READ;
  2641.  
  2642.   procedure READ             ( ITEM : in out string; LAST : in out integer ) is
  2643.   begin
  2644.     GET_LINE ( CURRENT_FILE, ITEM, LAST );
  2645.   end READ;
  2646.  
  2647.   procedure WRITE             ( ITEM : in    float  ) is
  2648.   begin
  2649.     PUT ( CURRENT_FILE, ITEM );
  2650.     NEW_LINE ( CURRENT_FILE );
  2651.   end WRITE;
  2652.  
  2653.   procedure WRITE             ( ITEM : in    string ) is
  2654.   begin
  2655.     PUT ( CURRENT_FILE, ITEM ( ITEM'first .. ITEM'last) );
  2656.     NEW_LINE ( CURRENT_FILE );
  2657.   end WRITE;
  2658.  
  2659.   procedure WRITE_DISPLAY_CURRENTS is
  2660.   begin
  2661.     WRITE ( CURRENT_MAP_TITLE );
  2662.     WRITE ( KIND_OF_PROJECTION'image ( CURRENT_TYPE_OF_PROJECTION ) );
  2663.     WRITE ( CURRENT_PROJECTION.LAT_CENTER );
  2664.     WRITE ( CURRENT_PROJECTION.LON_CENTER );
  2665.     WRITE ( CURRENT_PROJECTION.CLK_ROT_AR_CENT );
  2666.     WRITE ( CURRENT_PROJECTION.SAT_ALTITUDE );
  2667.     WRITE ( CURRENT_PROJECTION.VIEW_ALTITUDE );
  2668.     WRITE ( KIND_OF_PROJECTION_LIMIT'image ( CURRENT_TYPE_OF_PROJECTION_LIMIT ) );
  2669.     WRITE ( CURRENT_PROJECTION_LIM.MIN_LAT_LON.X );
  2670.     WRITE ( CURRENT_PROJECTION_LIM.MIN_LAT_LON.Y );
  2671.     WRITE ( CURRENT_PROJECTION_LIM.MAX_LAT_LON.X );
  2672.     WRITE ( CURRENT_PROJECTION_LIM.MAX_LAT_LON.Y );
  2673.     WRITE ( CURRENT_PROJECTION_LIM.NORTH_EAST.X );
  2674.     WRITE ( CURRENT_PROJECTION_LIM.NORTH_EAST.Y );
  2675.     WRITE ( CURRENT_PROJECTION_LIM.SOUTH_WEST.X );
  2676.     WRITE ( CURRENT_PROJECTION_LIM.SOUTH_WEST.Y );
  2677.     WRITE ( CURRENT_PROJECTION_LIM.ANGLE_UP );
  2678.     WRITE ( CURRENT_PROJECTION_LIM.ANGLE_DOWN );
  2679.     WRITE ( CURRENT_PROJECTION_LIM.ANGLE_RIGHT );
  2680.     WRITE ( CURRENT_PROJECTION_LIM.ANGLE_LEFT );
  2681.     WRITE ( CURRENT_PROJECTION_LIM.POINT_UP.X );
  2682.     WRITE ( CURRENT_PROJECTION_LIM.POINT_UP.Y );
  2683.     WRITE ( CURRENT_PROJECTION_LIM.POINT_DOWN.X );
  2684.     WRITE ( CURRENT_PROJECTION_LIM.POINT_DOWN.Y );
  2685.     WRITE ( CURRENT_PROJECTION_LIM.POINT_RIGHT.X );
  2686.     WRITE ( CURRENT_PROJECTION_LIM.POINT_RIGHT.Y );
  2687.     WRITE ( CURRENT_PROJECTION_LIM.POINT_LEFT.X );
  2688.     WRITE ( CURRENT_PROJECTION_LIM.POINT_LEFT.Y );
  2689.     WRITE ( COLOR_TYPE'image ( CURRENT_COLOR.BACKGROUND ) );
  2690.     WRITE ( COLOR_TYPE'image ( CURRENT_COLOR.DEFAULT ) );
  2691.     WRITE ( COLOR_TYPE'image ( CURRENT_COLOR.MAP_OUTLINE ) );
  2692.     WRITE ( COLOR_TYPE'image ( CURRENT_COLOR.GRID_LINES ) );
  2693.     WRITE ( COLOR_TYPE'image ( CURRENT_COLOR.HORIZON ) );
  2694.     WRITE ( boolean'image ( CURRENT_GRID_LINES.SHOW_LINES ) );
  2695.     WRITE ( CURRENT_GRID_LINES.DEGREES_BTWN_LATS );
  2696.     WRITE ( CURRENT_GRID_LINES.DEGREES_BTWN_LONS );
  2697.     WRITE ( CURRENT_GRID_LINES.SEGMENT_LENGTH );
  2698. --    WRITE ( boolean'image ( CURRENT_CLIPPING ) );
  2699.     WRITE ( boolean'image ( CURRENT_LAND ) );
  2700.   exception
  2701.     when others =>
  2702.       raise CONSTRAINT_ERROR;
  2703.   end WRITE_DISPLAY_CURRENTS;
  2704.  
  2705.   procedure WRITE_SESSION_CURRENTS is
  2706.   begin
  2707.     WRITE_DISPLAY_CURRENTS;
  2708.     WRITE ( CURRENT_SPECIALS.BEAM_DATA );
  2709.     WRITE ( COLOR_TYPE'image ( CURRENT_SPECIALS.BEAM_COLOR ) );
  2710.     WRITE ( integer'image ( CURRENT_SPECIALS.BEAM_LAST ) );
  2711.     WRITE ( CURRENT_SPECIALS.SWATH_DATA );
  2712.     WRITE ( COLOR_TYPE'image ( CURRENT_SPECIALS.SWATH_COLOR ) );
  2713.     WRITE ( integer'image ( CURRENT_SPECIALS.SWATH_LAST ) );
  2714.     WRITE ( CURRENT_SPECIALS.POINTS_DATA );
  2715.     WRITE ( COLOR_TYPE'image ( CURRENT_SPECIALS.POINTS_COLOR ) );
  2716.     WRITE ( integer'image ( CURRENT_SPECIALS.POINTS_LAST ) );
  2717.     WRITE ( boolean'image ( CURRENT_DIAGS.WARNING ) );
  2718.     WRITE ( boolean'image ( CURRENT_DIAGS.ERROR ) );
  2719.     WRITE ( boolean'image ( CURRENT_DIAGS.FATAL ) );
  2720.     WRITE ( CURRENT_PLOT_CHARACTERISTICS.AXIS_LENGTH.X );
  2721.     WRITE ( CURRENT_PLOT_CHARACTERISTICS.AXIS_LENGTH.Y );
  2722.     WRITE ( CURRENT_PLOT_CHARACTERISTICS.ORIGIN.X );
  2723.     WRITE ( CURRENT_PLOT_CHARACTERISTICS.ORIGIN.Y ); 
  2724.   exception
  2725.     when others =>
  2726.       raise CONSTRAINT_ERROR;
  2727.   end WRITE_SESSION_CURRENTS;
  2728.  
  2729.   procedure READ_DISPLAY_DEFAULTS is
  2730.   begin
  2731.     READ ( DEFAULT_MAP_TITLE, LAST );
  2732.     READ ( HOLD_STRING, LAST );
  2733.     DEFAULT_TYPE_OF_PROJECTION := KIND_OF_PROJECTION'value 
  2734.                                     ( HOLD_STRING ( 1 .. LAST ) );
  2735.     READ ( DEFAULT_PROJECTION.LAT_CENTER );
  2736.     READ ( DEFAULT_PROJECTION.LON_CENTER );
  2737.     READ ( DEFAULT_PROJECTION.CLK_ROT_AR_CENT );
  2738.     READ ( DEFAULT_PROJECTION.SAT_ALTITUDE );
  2739.     READ ( DEFAULT_PROJECTION.VIEW_ALTITUDE );
  2740.     READ ( HOLD_STRING, LAST );
  2741.     DEFAULT_TYPE_OF_PROJECTION_LIMIT := KIND_OF_PROJECTION_LIMIT'value 
  2742.                                     ( HOLD_STRING ( 1 .. LAST ) );
  2743.     READ ( DEFAULT_PROJECTION_LIM.MIN_LAT_LON.X );
  2744.     READ ( DEFAULT_PROJECTION_LIM.MIN_LAT_LON.Y );
  2745.     READ ( DEFAULT_PROJECTION_LIM.MAX_LAT_LON.X );
  2746.     READ ( DEFAULT_PROJECTION_LIM.MAX_LAT_LON.Y );
  2747.     READ ( DEFAULT_PROJECTION_LIM.NORTH_EAST.X );
  2748.     READ ( DEFAULT_PROJECTION_LIM.NORTH_EAST.Y );
  2749.     READ ( DEFAULT_PROJECTION_LIM.SOUTH_WEST.X );
  2750.     READ ( DEFAULT_PROJECTION_LIM.SOUTH_WEST.Y );
  2751.     READ ( DEFAULT_PROJECTION_LIM.ANGLE_UP );
  2752.     READ ( DEFAULT_PROJECTION_LIM.ANGLE_DOWN );
  2753.     READ ( DEFAULT_PROJECTION_LIM.ANGLE_RIGHT );
  2754.     READ ( DEFAULT_PROJECTION_LIM.ANGLE_LEFT );
  2755.     READ ( DEFAULT_PROJECTION_LIM.POINT_UP.X );
  2756.     READ ( DEFAULT_PROJECTION_LIM.POINT_UP.Y );
  2757.     READ ( DEFAULT_PROJECTION_LIM.POINT_DOWN.X );
  2758.     READ ( DEFAULT_PROJECTION_LIM.POINT_DOWN.Y );
  2759.     READ ( DEFAULT_PROJECTION_LIM.POINT_RIGHT.X );
  2760.     READ ( DEFAULT_PROJECTION_LIM.POINT_RIGHT.Y );
  2761.     READ ( DEFAULT_PROJECTION_LIM.POINT_LEFT.X );
  2762.     READ ( DEFAULT_PROJECTION_LIM.POINT_LEFT.Y );
  2763.     READ ( HOLD_STRING, LAST );
  2764.     DEFAULT_COLOR.BACKGROUND := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  2765.     READ ( HOLD_STRING, LAST );
  2766.     DEFAULT_COLOR.DEFAULT := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  2767.     READ ( HOLD_STRING, LAST );
  2768.     DEFAULT_COLOR.MAP_OUTLINE := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  2769.     READ ( HOLD_STRING, LAST );
  2770.     DEFAULT_COLOR.GRID_LINES := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  2771.     READ ( HOLD_STRING, LAST );
  2772.     DEFAULT_COLOR.HORIZON := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  2773.     READ ( HOLD_STRING, LAST );
  2774.     DEFAULT_GRID_LINES.SHOW_LINES := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  2775.     READ ( DEFAULT_GRID_LINES.DEGREES_BTWN_LATS );
  2776.     READ ( DEFAULT_GRID_LINES.DEGREES_BTWN_LONS );
  2777.     READ ( DEFAULT_GRID_LINES.SEGMENT_LENGTH );
  2778. --    READ ( HOLD_STRING, LAST );
  2779. --    DEFAULT_CLIPPING := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  2780.     READ ( HOLD_STRING, LAST );
  2781.     DEFAULT_LAND := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  2782.   exception
  2783.     when others =>
  2784.       raise CONSTRAINT_ERROR;
  2785.   end READ_DISPLAY_DEFAULTS;
  2786.  
  2787.   procedure READ_SESSION_DEFAULTS is
  2788.   begin
  2789.     READ_DISPLAY_DEFAULTS;
  2790.     READ ( DEFAULT_SPECIALS.BEAM_DATA, LAST );
  2791.     READ ( HOLD_STRING, LAST );
  2792.     DEFAULT_SPECIALS.BEAM_COLOR := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  2793.     READ ( HOLD_STRING, LAST );
  2794.     DEFAULT_SPECIALS.BEAM_LAST := integer'value ( HOLD_STRING ( 1 .. LAST ) );
  2795.     READ ( DEFAULT_SPECIALS.SWATH_DATA, LAST );
  2796.     READ ( HOLD_STRING, LAST );
  2797.     DEFAULT_SPECIALS.SWATH_COLOR := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  2798.     READ ( HOLD_STRING, LAST );
  2799.     DEFAULT_SPECIALS.SWATH_LAST := integer'value ( HOLD_STRING ( 1 .. LAST ) );
  2800.     READ ( DEFAULT_SPECIALS.POINTS_DATA, LAST );
  2801.     READ ( HOLD_STRING, LAST );
  2802.     DEFAULT_SPECIALS.POINTS_COLOR := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  2803.     READ ( HOLD_STRING, LAST );
  2804.     DEFAULT_SPECIALS.POINTS_LAST := integer'value ( HOLD_STRING ( 1 .. LAST ) );
  2805.     READ ( HOLD_STRING, LAST );
  2806.     DEFAULT_DIAGS.WARNING := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  2807.     READ ( HOLD_STRING, LAST );
  2808.     DEFAULT_DIAGS.ERROR := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  2809.     READ ( HOLD_STRING, LAST );
  2810.     DEFAULT_DIAGS.FATAL := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  2811.     READ ( DEFAULT_PLOT_CHARACTERISTICS.AXIS_LENGTH.X );
  2812.     READ ( DEFAULT_PLOT_CHARACTERISTICS.AXIS_LENGTH.Y );
  2813.     READ ( DEFAULT_PLOT_CHARACTERISTICS.ORIGIN.X );
  2814.     READ ( DEFAULT_PLOT_CHARACTERISTICS.ORIGIN.Y ); 
  2815.   exception
  2816.     when others =>
  2817.       raise CONSTRAINT_ERROR;
  2818.   end READ_SESSION_DEFAULTS;
  2819.  
  2820. end MENU_FILE_IO;
  2821. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2822. --worlddata.txt
  2823. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2824. package body WORLD_DATA_FILES is
  2825.  
  2826. begin
  2827.  
  2828.   null;
  2829.  
  2830. end WORLD_DATA_FILES;
  2831. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2832. --termfunct.txt
  2833. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2834. with TEXT_IO;
  2835. package body TERM_FUNCTIONS is
  2836.  
  2837.   use  TEXT_IO;
  2838.  
  2839.   C         :      character  := ' ';
  2840.  
  2841.   BUF      :      string ( 1 .. 80 ) := ( 1 .. 80 => ' ' );
  2842.   BUF_INDEX :      integer := 1;
  2843.  
  2844.   package FLT_IO is new FLOAT_IO ( FLOAT );
  2845.  
  2846.   procedure PUT_STRING ( ITEM : in string ) is
  2847.   begin
  2848.     PUT ( ITEM ( ITEM'first .. ITEM'last ) );
  2849.   end PUT_STRING;
  2850.  
  2851.   procedure GET_CHAR ( ITEM : in out character ) is
  2852.   begin
  2853.     GET ( ITEM );
  2854.   end GET_CHAR;
  2855.  
  2856.   procedure SET_TOP_AND_BOTTOM_MARGINS ( TOP, BOTTOM : in POSITIVE_NUMBER ) is
  2857.     TEMPTOP      :      constant string := integer'image ( TOP );
  2858.     TEMPBOTTOM   :      constant string := integer'image ( BOTTOM );
  2859.   begin
  2860.     PUT ( ASCII.ESC );
  2861.     PUT ( "[" & TEMPTOP ( 2 .. TEMPTOP'last ) & ";" & 
  2862.           TEMPBOTTOM ( 2 .. TEMPBOTTOM'last ) & "r"  );
  2863.   end SET_TOP_AND_BOTTOM_MARGINS;
  2864.   
  2865.   procedure SET_HOME is
  2866.   begin
  2867.     PUT ( ASCII.ESC );
  2868.     PUT ( "[?6h" );
  2869.   end SET_HOME;
  2870.   
  2871.   procedure RESET_HOME is
  2872.   begin
  2873.     PUT ( ASCII.ESC );
  2874.     PUT ( "[?6l" );
  2875.   end RESET_HOME;
  2876.   
  2877.   procedure POSITION_CURSOR ( ITEM : in CURSOR_POS ) is
  2878.    TEMPLINE      :      constant string := integer'image ( ITEM.LINE );
  2879.    TEMPCOLUMN    :      constant string := integer'image ( ITEM.COLUMN );
  2880.   begin
  2881.     PUT ( ASCII.ESC );
  2882.     PUT ( "[" & TEMPLINE ( 2 .. TEMPLINE'last ) & ";" &
  2883.           TEMPCOLUMN ( 2 .. TEMPCOLUMN'last )   & "H"  );
  2884.   end POSITION_CURSOR;
  2885.   
  2886.   procedure CURSOR_HOME is
  2887.   begin
  2888.     PUT ( ASCII.ESC );
  2889.     PUT ( "[H" );
  2890.   end CURSOR_HOME;
  2891.   
  2892.   function PARSE_INPUT return TOKEN is
  2893.  
  2894.     TEMP      :      TOKEN      := ALPHA_NUM;
  2895.     LEN       :      integer           := 0;
  2896.  
  2897.   begin
  2898.  
  2899.     SET_LOCAL_ECHO;
  2900.  
  2901.     GET ( C );
  2902.     if C = ' ' then
  2903.       TEMP := RETURN_KEY;
  2904.     elsif C = ascii.ht then
  2905.       TEMP := TAB;
  2906.     elsif C = ascii.bs then
  2907.       TEMP := BACK_SPACE;
  2908.     elsif C = ascii.esc then
  2909.       GET ( C );
  2910.       GET ( C );
  2911.       if C = 'A' then
  2912.         TEMP := UP_ARROW;
  2913.       elsif C = 'B' then
  2914.         TEMP := DOWN_ARROW;
  2915.       elsif C = 'C' then
  2916.         TEMP := RIGHT_ARROW;
  2917.       else
  2918.         TEMP := LEFT_ARROW;
  2919.       end if;
  2920.     end if;
  2921.  
  2922.     return TEMP;
  2923.  
  2924.   end PARSE_INPUT;
  2925.   
  2926.   function PARSED_CHAR      return      CHARACTER is
  2927.   begin
  2928.     return C;
  2929.   end PARSED_CHAR;
  2930.  
  2931.   procedure SET_132_COLUMNS_PER_LINE is
  2932.   begin
  2933.     PUT ( ASCII.ESC );
  2934.     PUT ( "[?3h" );
  2935.   end SET_132_COLUMNS_PER_LINE;
  2936.   
  2937.   procedure SET_80_COLUMNS_PER_LINE is
  2938.   begin
  2939.     PUT ( ASCII.ESC );
  2940.     PUT ( "[?3l" );
  2941.   end SET_80_COLUMNS_PER_LINE;
  2942.   
  2943.   procedure SET_LOCAL_ECHO is   -- TURNS OFF WHAT YOU TYPE!
  2944.   begin
  2945.     PUT ( ASCII.ESC );
  2946.     PUT ( "[12h" );
  2947.   end SET_LOCAL_ECHO;
  2948.   
  2949.   procedure RESET_LOCAL_ECHO is  -- Turns on what you type.
  2950.   begin
  2951.     PUT ( ASCII.ESC );
  2952.     PUT ( "[12l" );
  2953.   end RESET_LOCAL_ECHO;
  2954.   
  2955.   function STRING_FL ( ITEM : in string ) return float is
  2956.     VALR      :            float := 0.0;
  2957.     TEMP      :            positive := 15;
  2958.   begin
  2959.     FLT_IO.GET ( ITEM ( ITEM'first .. ITEM'last ), VALR, TEMP );
  2960.     return VALR;
  2961.   end STRING_FL;
  2962.  
  2963.   function FL_STRING ( ITEM : in float ) return string is
  2964.     TEMP      :      string ( 1 .. 12 ) := ( 1 .. 12 => ' ' );
  2965.   begin
  2966.     FLT_IO.PUT ( TEMP, ITEM );
  2967.     return TEMP;
  2968.   end FL_STRING;
  2969.  
  2970.   procedure FILL ( CONSTRAIN : in integer ) is
  2971.   begin
  2972.     if C = ascii.BS then
  2973.       if BUF_INDEX /= 1 then
  2974.         BUF_INDEX := BUF_INDEX - 1;
  2975.         BUF ( BUF_INDEX ) := ' ';
  2976.         PUT ( C );
  2977.       end if;
  2978.     elsif BUF_INDEX <= CONSTRAIN then
  2979.       BUF ( BUF_INDEX ) := C;
  2980.       BUF_INDEX := BUF_INDEX + 1;
  2981.       PUT ( C );
  2982.     end if;
  2983.   end FILL;
  2984.  
  2985.   procedure FLUSH ( ITEM : out STRING; LAST : out integer ) is
  2986.   begin
  2987.     LAST := 0;
  2988.     if BUF_INDEX /= 1 then
  2989.       ITEM := BUF ( 1 .. ITEM'last );
  2990.       LAST := BUF_INDEX - 1;
  2991.       if BUF_INDEX <= ITEM'last then
  2992.         PUT ( BUF ( BUF_INDEX .. ITEM'last ) ); -- BLANKS
  2993.       end if;
  2994.       BUF_INDEX := 1;
  2995.       BUF ( 1 .. BUF'last ) := ( 1 .. BUF'last => ' ' );
  2996.     end if;
  2997.   end FLUSH;
  2998.  
  2999. begin
  3000.   null;
  3001. end TERM_FUNCTIONS;
  3002. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3003. --menutypes.txt
  3004. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3005. package body MENU_TYPES is
  3006. begin
  3007.   null;
  3008. end MENU_TYPES;
  3009. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3010. --menutext.txt
  3011. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3012. package body MENU_TEXT is
  3013. begin
  3014.   null;
  3015. end MENU_TEXT;
  3016. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3017. --menucurre.txt
  3018. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3019. package body MENU_CURRENTS is
  3020.  
  3021.   procedure SET_CURRENTS_FROM_DEFAULTS is
  3022.   begin
  3023.     CURRENT_TYPE_OF_PROJECTION       := DEFAULT_TYPE_OF_PROJECTION;
  3024.     CURRENT_TYPE_OF_PROJECTION_LIMIT := DEFAULT_TYPE_OF_PROJECTION_LIMIT;
  3025.     CURRENT_MAP_TITLE                := DEFAULT_MAP_TITLE;
  3026.     CURRENT_GRID_LINES               := DEFAULT_GRID_LINES;
  3027.     CURRENT_COLOR                    := DEFAULT_COLOR;
  3028.     CURRENT_SPECIALS                 := DEFAULT_SPECIALS;
  3029.     CURRENT_PROJECTION               := DEFAULT_PROJECTION;
  3030.     CURRENT_PROJECTION_LIM           := DEFAULT_PROJECTION_LIM;
  3031.     CURRENT_PLOT_CHARACTERISTICS     := DEFAULT_PLOT_CHARACTERISTICS;
  3032. --    CURRENT_CLIPPING                 := DEFAULT_CLIPPING;
  3033.     CURRENT_LAND                     := DEFAULT_LAND;
  3034.     CURRENT_DIAGS                    := DEFAULT_DIAGS;
  3035.   end SET_CURRENTS_FROM_DEFAULTS;
  3036.  
  3037.   procedure SET_DEFAULTS_FROM_CURRENTS is
  3038.   begin
  3039.     DEFAULT_TYPE_OF_PROJECTION       := CURRENT_TYPE_OF_PROJECTION;
  3040.     DEFAULT_TYPE_OF_PROJECTION_LIMIT := CURRENT_TYPE_OF_PROJECTION_LIMIT;
  3041.     DEFAULT_MAP_TITLE                := CURRENT_MAP_TITLE;
  3042.     DEFAULT_GRID_LINES               := CURRENT_GRID_LINES;
  3043.     DEFAULT_COLOR                    := CURRENT_COLOR;
  3044.     DEFAULT_SPECIALS                 := CURRENT_SPECIALS;
  3045.     DEFAULT_PROJECTION               := CURRENT_PROJECTION;
  3046.     DEFAULT_PROJECTION_LIM           := CURRENT_PROJECTION_LIM;
  3047.     DEFAULT_PLOT_CHARACTERISTICS     := CURRENT_PLOT_CHARACTERISTICS;
  3048. --    DEFAULT_CLIPPING                 := CURRENT_CLIPPING;
  3049.     DEFAULT_LAND                     := CURRENT_LAND;
  3050.     DEFAULT_DIAGS                    := CURRENT_DIAGS;
  3051.   end SET_DEFAULTS_FROM_CURRENTS;
  3052. begin
  3053.   null;
  3054. end MENU_CURRENTS;
  3055. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3056. --worldmenu.txt
  3057. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3058. with MENU_CURRENTS, MENU_PARSE, MENU_DRAW;
  3059. package body WORLD_MENUS is
  3060.  
  3061.   use  MENU_CURRENTS, MENU_TYPES, GRAPHIC, MENU_PARSE, MENU_DRAW;
  3062.  
  3063.   function END_OF_SESSION                return boolean is
  3064.   begin
  3065.     return SESSION_TERMINATED;
  3066.   end END_OF_SESSION;
  3067.  
  3068.   function TYPE_OF_PROJECTION            return KIND_OF_PROJECTION is
  3069.   begin
  3070.     return CURRENT_TYPE_OF_PROJECTION;
  3071.   end TYPE_OF_PROJECTION;
  3072.  
  3073.   function TYPE_OF_PROJECTION_LIMIT      return KIND_OF_PROJECTION_LIMIT is
  3074.   begin
  3075.     return CURRENT_TYPE_OF_PROJECTION_LIMIT;
  3076.   end TYPE_OF_PROJECTION_LIMIT;
  3077.  
  3078. --  function CLIPPING                      return boolean is
  3079. --  begin
  3080. --    return CURRENT_CLIPPING;
  3081. --  end CLIPPING;
  3082.  
  3083.   function CURRENT_TITLE                 return MAP_TITLE is
  3084.   begin
  3085.     return CURRENT_MAP_TITLE;
  3086.   end CURRENT_TITLE;
  3087.  
  3088.   function CURRENT_PROJECTION_PARAMETERS return PROJECTION_PARAMETERS is
  3089.   begin
  3090.     return CURRENT_PROJECTION;
  3091.   end CURRENT_PROJECTION_PARAMETERS;
  3092.  
  3093.   function CURRENT_PROJECTION_LIMITS     return PROJECTION_LIMITS is
  3094.   begin
  3095.     return CURRENT_PROJECTION_LIM;
  3096.   end CURRENT_PROJECTION_LIMITS;
  3097.  
  3098.   function CURRENT_GRID_LINE_PARAMETERS  return GRID_LINE_PARAMETERS is
  3099.   begin
  3100.     return CURRENT_GRID_LINES;
  3101.   end CURRENT_GRID_LINE_PARAMETERS;
  3102.  
  3103.   function CURRENT_COLOR_SELECTION       return COLOR_SELECTION is
  3104.   begin
  3105.     return CURRENT_COLOR;
  3106.   end CURRENT_COLOR_SELECTION;
  3107.  
  3108.   function CURRENT_SPECIAL_DISPLAYS      return SPECIAL_DISPLAYS is
  3109.   begin
  3110.     return CURRENT_SPECIALS;
  3111.   end CURRENT_SPECIAL_DISPLAYS;
  3112.  
  3113.   function CURRENT_DIAGNOSTICS           return DIAGNOSTICS is
  3114.   begin
  3115.     return CURRENT_DIAGS;
  3116.   end CURRENT_DIAGNOSTICS;
  3117.  
  3118.   function CURRENT_PLOT_CHAR             return PLOT_CHARACTERISTICS is
  3119.   begin
  3120.     return CURRENT_PLOT_CHARACTERISTICS;
  3121.   end CURRENT_PLOT_CHAR;
  3122.  
  3123.   function PLOT_LAND                     return boolean is
  3124.   begin
  3125.     return CURRENT_LAND;
  3126.   end PLOT_LAND;
  3127.  
  3128.   function SHOW_GRID                     return boolean is
  3129.   begin
  3130.     return CURRENT_GRID_LINES.SHOW_LINES;
  3131.   end SHOW_GRID;
  3132.  
  3133.   function SHOW_BEAM                     return boolean is
  3134.     TEMP      :      boolean      := false;
  3135.   begin
  3136.     if CURRENT_SPECIALS.BEAM_LAST /= 0 then
  3137.       TEMP := true;
  3138.     end if;
  3139.     return TEMP;
  3140.   end SHOW_BEAM;
  3141.  
  3142.   function SHOW_SWATH                    return boolean is
  3143.     TEMP      :      boolean      := false;
  3144.   begin
  3145.     if CURRENT_SPECIALS.SWATH_LAST /= 0 then
  3146.       TEMP := true;
  3147.     end if;
  3148.     return TEMP;
  3149.   end SHOW_SWATH;
  3150.  
  3151.   procedure GENERATE_MENUS is
  3152.     MENU      :      MENUS        := CURRENT_MENU;
  3153.   begin
  3154.     DRAW_MAP := false;
  3155.     loop
  3156.       case PARSE_COMMAND_LINE is
  3157.         when EDIT               =>
  3158.           EDIT;
  3159.         when CONTINUE           =>
  3160.           CONTINUE;
  3161.         when SAVE               =>
  3162.           SAVE;
  3163. --        when HELP               =>
  3164. --          HELP;
  3165.         when LEAVE              =>
  3166.           LEAVE;
  3167.         when QUIT               =>
  3168.           QUIT;
  3169. --        when UNDO               =>
  3170. --          UNDO;
  3171.         when SPECIAL            =>
  3172.           SPECIAL;
  3173. --        when APPEND             =>
  3174. --          APPEND;
  3175.         when OPENF              =>
  3176.           OPENF;
  3177.         when others             =>
  3178.           null;
  3179.       end case;
  3180.       exit when DRAW_MAP;
  3181.     end loop;
  3182.  
  3183.   end GENERATE_MENUS;
  3184.  
  3185.   procedure INITIALIZE is
  3186.   begin
  3187.  
  3188.   DRAW_MAP := FALSE;
  3189.   CURRENT_TYPE_OF_PROJECTION        :=      CARTESIAN;
  3190.   CURRENT_TYPE_OF_PROJECTION_LIMIT  :=      MIN_MAX_COORDINATES;
  3191.   DEFAULT_TYPE_OF_PROJECTION        :=      CURRENT_TYPE_OF_PROJECTION;
  3192.   DEFAULT_TYPE_OF_PROJECTION_LIMIT  :=      CURRENT_TYPE_OF_PROJECTION_LIMIT;
  3193.   
  3194.   for I in MAP_TITLE'range loop
  3195.     CURRENT_MAP_TITLE ( I )         := ' ';
  3196.   end loop;
  3197.   DEFAULT_MAP_TITLE                 := CURRENT_MAP_TITLE;
  3198.  
  3199.   SESSION_TERMINATED                :=      false;
  3200.  
  3201.   CURRENT_GRID_LINES                := ( SHOW_LINES        => true,
  3202.                                          DEGREES_BTWN_LATS => 45.0,
  3203.                                          DEGREES_BTWN_LONS => 45.0,
  3204.                                          SEGMENT_LENGTH    => 4.0  );
  3205.   DEFAULT_GRID_LINES                := CURRENT_GRID_LINES;
  3206.  
  3207.   CURRENT_COLOR                     := ( BACKGROUND        => GRAPHIC.BLACK,
  3208.                                          DEFAULT           => GRAPHIC.BLUE,
  3209.                                          MAP_OUTLINE       => GRAPHIC.GREEN,
  3210.                                          GRID_LINES        => GRAPHIC.RED,
  3211.                                          HORIZON           => GRAPHIC.BLUE  );
  3212.   DEFAULT_COLOR                     := CURRENT_COLOR;
  3213.  
  3214.   CURRENT_SPECIALS                  := ( BEAM_DATA         => "          " &
  3215.                                 "          " & "          " & "          ",
  3216.                                          BEAM_COLOR        => GRAPHIC.BLUE,
  3217.                                          BEAM_LAST         => 0,
  3218.                                          SWATH_DATA        => "          " &
  3219.                                 "          " & "          " & "          ",
  3220.                                          SWATH_COLOR       => GRAPHIC.RED,
  3221.                                          SWATH_LAST         => 0,
  3222.                                          POINTS_DATA       => "WORLDPTS.D" &
  3223.                                 "AT        " & "          " & "          ",
  3224.                                          POINTS_COLOR      => GRAPHIC.GREEN,
  3225.                                          POINTS_LAST         => 12            );
  3226.  
  3227.   DEFAULT_SPECIALS                  := CURRENT_SPECIALS;
  3228.  
  3229. --  CURRENT_PROJECTION                := ( KIND              => SATELLITE,
  3230. --                                         LAT_CENTER        => 0.0,
  3231. --                                         LON_CENTER        => 0.0,
  3232. --                                         CLK_ROT_AR_CENT   => 0.0,
  3233. --                                         SAT_ALTITUDE      => 0.0,
  3234. --                                         VIEW_ALTITUDE     => 0.0      );
  3235.  
  3236.   CURRENT_PROJECTION                := ( LAT_CENTER        => 0.0,
  3237.                                          LON_CENTER        => 0.0,
  3238.                                          CLK_ROT_AR_CENT   => 0.0,
  3239.                                          SAT_ALTITUDE      => 0.0,
  3240.                                          VIEW_ALTITUDE     => 0.0      );
  3241.   DEFAULT_PROJECTION                := CURRENT_PROJECTION;
  3242.  
  3243. --  CURRENT_PROJECTION_LIM            := ( KIND              => MIN_MAX_LAT_LON,
  3244. --                                         MIN_LAT_LON       => ( X => 0.0, 
  3245. --                                                                Y => 0.0 ),
  3246. --                                         MAX_LAT_LON       => ( X => 0.0, 
  3247. --                                                                Y => 0.0 )    );
  3248.  
  3249.   CURRENT_PROJECTION_LIM            := ( MIN_LAT_LON       => ( X => 0.0, 
  3250.                                                                 Y => 0.0 ),
  3251.                                          MAX_LAT_LON       => ( X => 0.0, 
  3252.                                                                 Y => 0.0 ),
  3253.                                          NORTH_EAST        => ( X => 50.0,
  3254.                                                                 Y => 330.0 ),
  3255.                                          SOUTH_WEST        => ( X => 20.0,
  3256.                                                                 Y => 230.0 ),
  3257.                                          ANGLE_UP          => 0.0,
  3258.                                          ANGLE_DOWN        => 0.0,
  3259.                                          ANGLE_RIGHT       => 0.0,
  3260.                                          ANGLE_LEFT        => 0.0,
  3261.                                          POINT_UP          => ( X => 0.0,
  3262.                                                                 Y => 0.0 ),
  3263.                                          POINT_DOWN        => ( X => 0.0,
  3264.                                                                 Y => 0.0 ),
  3265.                                          POINT_RIGHT       => ( X => 0.0,
  3266.                                                                 Y => 0.0 ),
  3267.                                          POINT_LEFT        => ( X => 0.0,
  3268.                                                                 Y => 0.0 ) );
  3269.   DEFAULT_PROJECTION_LIM            := CURRENT_PROJECTION_LIM;
  3270.  
  3271.   STATUS                            := ( WARNING           => false,
  3272.                                          ERROR             => false,
  3273.                                          FATAL             => false    );
  3274.  
  3275.   CURRENT_DIAGS                     := ( WARNING           => true,
  3276.                                          ERROR             => true,
  3277.                                          FATAL             => true    );
  3278.   DEFAULT_DIAGS                     := CURRENT_DIAGS;
  3279.  
  3280. --  CURRENT_CLIPPING                  := true;
  3281. --  DEFAULT_CLIPPING                  := CURRENT_CLIPPING;
  3282.   CURRENT_LAND                      := true;
  3283.   DEFAULT_LAND                      := CURRENT_LAND;
  3284.  
  3285.   CURRENT_PLOT_CHARACTERISTICS      := ( AXIS_LENGTH   => ( X => 8.0, Y => 8.0 ),
  3286.                                          ORIGIN        => ( X => 0.0, Y => 0.0 ));
  3287.   DEFAULT_PLOT_CHARACTERISTICS      := CURRENT_PLOT_CHARACTERISTICS;
  3288.  
  3289.   CURRENT_SESSION_FILENAME          := ( 1 .. 40 => ' ' );
  3290.   CURRENT_DISPLAY_FILENAME          := CURRENT_SESSION_FILENAME;
  3291.  
  3292.   INITIALIZE_MENUS;
  3293.   INITIALIZE_PARSE;
  3294.  
  3295.   end INITIALIZE;
  3296.  
  3297. begin
  3298.   null;
  3299. end WORLD_MENUS;
  3300. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3301. --menuconst.txt
  3302. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3303. package body MENU_CONSTANTS is
  3304.  
  3305.   TEMP_POS      :      TERM_FUNCTIONS.CURSOR_POS;
  3306.  
  3307.   procedure INC ( AMOUNT : in integer ) is
  3308.   begin
  3309.     TEMP_POS.COLUMN := TEMP_POS.COLUMN + AMOUNT + 2;
  3310.   end INC;
  3311.  
  3312.   function X_Y_POS_ALT ( ITEM : in FIELD_INDEX ) return TERM_FUNCTIONS.CURSOR_POS is
  3313.   begin
  3314.  
  3315.     TEMP_POS := ( LINE => X_Y_POS ( ITEM ).LINE,
  3316.                   COLUMN => X_Y_POS ( ITEM ).COLUMN );
  3317.  
  3318.     case ITEM is
  3319.       when CI0 =>
  3320.         INC ( C0'length );
  3321.       when CI1 =>
  3322.         INC ( C1'length );
  3323.       when CI2 =>
  3324.         INC ( C2'length );
  3325.       when CI3 =>
  3326.         INC ( C3'length );
  3327.       when CI4 =>
  3328.         INC ( C4'length );
  3329.       when CI5 =>
  3330.         INC ( C5'length );
  3331.       when CI6 =>
  3332.         INC ( C6'length );
  3333.       when CI7 =>
  3334.         INC ( C7'length );
  3335.       when CI8 =>
  3336.         INC ( C8'length );
  3337.       when CI9 =>
  3338.         INC ( C9'length );
  3339.       when CI10 =>
  3340.         INC ( C10'length );
  3341.       when CI11 =>
  3342.         INC ( C11'length );
  3343.       when CI12 =>
  3344.         INC ( C12'length );
  3345.       when CI13 =>
  3346.         INC ( C13'length );
  3347.       when CI14 =>
  3348.         INC ( C14'length );
  3349.       when CI15 =>
  3350.         INC ( C15'length );
  3351.       when CI16 =>
  3352.         INC ( C16'length );
  3353.       when CI17 =>
  3354.         INC ( C17'length );
  3355.       when CI18 =>
  3356.         INC ( C18'length );
  3357.       when CI19 =>
  3358.         INC ( C19'length );
  3359.       when CI20 =>
  3360.         INC ( C20'length );
  3361.       when CI21 =>
  3362.         INC ( C21'length );
  3363.       when CI22 =>
  3364.         INC ( C22'length );
  3365.       when CI23 =>
  3366.         INC ( C23'length );
  3367.       when CI24 =>
  3368.         INC ( C24'length );
  3369.       when CI25 =>
  3370.         INC ( C25'length );
  3371.       when CI26 =>
  3372.         INC ( C26'length );
  3373.       when CI27 =>
  3374.         INC ( C27'length );
  3375.       when CI28 =>
  3376.         INC ( C28'length );
  3377.       when CI29 =>
  3378.         INC ( C29'length );
  3379.       when CI30 =>
  3380.         INC ( C30'length );
  3381.       when CI31 =>
  3382.         INC ( C31'length );
  3383.       when CI3A =>
  3384.         INC ( C3A'length );
  3385.       when CI3B =>
  3386.         INC ( C3B'length );
  3387.       when CI32 =>
  3388.         INC ( C32'length );
  3389.       when CI33 =>
  3390.         INC ( C33'length );
  3391.       when CI34 =>
  3392.         INC ( C34'length );
  3393.       when CI35 =>
  3394.         INC ( C35'length );
  3395.       when CI3C =>
  3396.         INC ( C3C'length );
  3397. --      when CI36 =>
  3398. --        INC ( C36'length );
  3399.       when CI37 =>
  3400.         INC ( C37'length );
  3401.       when CI38 =>
  3402.         INC ( C38'length );
  3403.       when CI39 =>
  3404.         INC ( C39'length );
  3405.       when CI40 =>
  3406.         INC ( C40'length );
  3407.       when CI41 =>
  3408.         INC ( C41'length );
  3409.       when CI42 =>
  3410.         INC ( C42'length );
  3411.       when CI43 =>
  3412.         INC ( C43'length );
  3413.       when CI44 =>
  3414.         INC ( C44'length );
  3415.       when CI45 =>
  3416.         INC ( C45'length );
  3417.       when CI46 =>
  3418.         INC ( C46'length );
  3419.       when CI47 =>
  3420.         INC ( C47'length );
  3421.       when CI48  =>
  3422.         INC ( C48'length );
  3423.       when CI49 =>
  3424.         INC ( C49'length );
  3425.       when CI50 =>
  3426.         INC ( C50'length );
  3427.       when CI51 =>
  3428.         INC ( C51'length );
  3429.       when CI52 =>
  3430.         INC ( C52'length );
  3431.       when others =>
  3432.         null;
  3433.     end case;
  3434.  
  3435.     return TEMP_POS;
  3436.  
  3437.   end X_Y_POS_ALT;
  3438.  
  3439. end MENU_CONSTANTS;
  3440. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3441. --trigf.txt
  3442. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3443. with TEXT_IO; use TEXT_IO;
  3444. with FLOATING_CHARACTERISTICS; use FLOATING_CHARACTERISTICS;
  3445. with NUMERIC_PRIMITIVES; use NUMERIC_PRIMITIVES;
  3446. with CORE_FUNCTIONS; use CORE_FUNCTIONS;
  3447. package body TRIG_LIB is
  3448.  
  3449.   package INT_IO is new INTEGER_IO ( INTEGER );
  3450.   package FLT_IO is new FLOAT_IO ( FLOAT );
  3451.   use INT_IO, FLT_IO;
  3452.  
  3453. --  PRELIMINARY VERSION *********************************
  3454.  
  3455. --  The following routines are coded directly from the algorithms and
  3456. --  coeficients given in "Software Manual for the Elementry Functions"
  3457. --  by William J. Cody, Jr. and William Waite, Prentice_Hall, 1980
  3458. --  This particular version is stripped to work with FLOAT and INTEGER
  3459. --  and uses a mantissa represented as a FLOAT
  3460. --  A more general formulation uses MANTISSA_TYPE, etc.
  3461. --  The coeficients are appropriate for 25 to 32 bits floating significance
  3462. --  They will work for less but slightly shorter versions are possible
  3463. --  The routines are coded to stand alone so they need not be compiled together
  3464.  
  3465. --      16 JULY 1982       W A WHITAKER  AFATL EGLIN AFB FL 32542
  3466. --                         T C EICHOLTZ  USAFA
  3467.  
  3468.  
  3469.   function SIN(X : FLOAT) return FLOAT is
  3470.     SGN, Y : FLOAT;
  3471.     N : INTEGER;
  3472.     XN : FLOAT;
  3473.     F, G, X1, X2 : FLOAT;
  3474.     RESULT : FLOAT;
  3475.  
  3476.     YMAX : FLOAT := FLOAT(INTEGER(PI * TWO**(IT/2)));
  3477.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  3478.     epsilon : FLOAT := BETA ** (-IT/2);
  3479.  
  3480.     C1 : constant FLOAT :=  3.140625;
  3481.     C2 : constant FLOAT :=  9.6765_35897_93E-4;
  3482.  
  3483.     function R(G : FLOAT) return FLOAT is
  3484.       R1 : constant FLOAT := -0.16666_66660_883;
  3485.       R2 : constant FLOAT :=  0.83333_30720_556E-2;
  3486.       R3 : constant FLOAT := -0.19840_83282_313E-3;
  3487.       R4 : constant FLOAT :=  0.27523_97106_775E-5;
  3488.       R5 : constant FLOAT := -0.23868_34640_601E-7;
  3489.     begin
  3490.       return ((((R5*G + R4)*G + R3)*G + R2)*G + R1)*G;
  3491.     end R;
  3492.  
  3493.   begin
  3494.     if X < ZERO  then
  3495.       SGN := -ONE;
  3496.       Y := -X;
  3497.     else
  3498.       SGN := ONE;
  3499.       Y := X;
  3500.     end if;
  3501.     if Y > YMAX  then
  3502.       NEW_LINE;
  3503.       PUT(" SIN CALLED WITH ARGUMENT TOO LARGE FOR ACCURACY ");
  3504.       PUT(X); NEW_LINE;
  3505.     end if;
  3506.  
  3507.     N := INTEGER(Y * ONE_OVER_PI);
  3508.     XN := CONVERT_TO_FLOAT(N);
  3509.     if N mod 2 /= 0  then
  3510.       SGN := -SGN;
  3511.     end if;
  3512.     X1 := TRUNCATE(ABS(X));
  3513.     X2 := ABS(X) - X1;
  3514.     F := ((X1 - XN*C1) + X2) - XN*C2;
  3515.     if ABS(F) < EPSILON  then
  3516.       RESULT := F;
  3517.     else
  3518.       G := F * F;
  3519.       RESULT := F + F*R(G);
  3520.     end if;
  3521.     return (SGN * RESULT);
  3522.   end SIN;
  3523.  
  3524.  
  3525.   function COS(X : FLOAT) return FLOAT is
  3526.     SGN, Y : FLOAT;
  3527.     N : INTEGER;
  3528.     XN : FLOAT;
  3529.     F, G, X1, X2 : FLOAT;
  3530.     RESULT : FLOAT;
  3531.  
  3532.     YMAX : FLOAT := FLOAT(INTEGER(PI * TWO**(IT/2)));
  3533.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  3534.     EPSILON : FLOAT := BETA ** (-IT/2);
  3535.  
  3536.     C1 : constant FLOAT :=  3.140625;
  3537.     C2 : constant FLOAT :=  9.6765_35897_93E-4;
  3538.  
  3539.     function R(G : FLOAT) return FLOAT is
  3540.       R1 : constant FLOAT := -0.16666_66660_883;
  3541.       R2 : constant FLOAT :=  0.83333_30720_556E-2;
  3542.       R3 : constant FLOAT := -0.19840_83282_313E-3;
  3543.       R4 : constant FLOAT :=  0.27523_97106_775E-5;
  3544.       R5 : constant FLOAT := -0.23868_34640_601E-7;
  3545.     begin
  3546.       return ((((R5*G + R4)*G + R3)*G + R2)*G + R1)*G;
  3547.     end R;
  3548.  
  3549.   begin
  3550.     SGN := 1.0;
  3551.     Y := ABS(X) + PI_OVER_TWO;
  3552.  
  3553.     if Y > YMAX  then
  3554.       NEW_LINE;
  3555.       PUT(" COS CALLED WITH ARGUMENT TOO LARGE FOR ACCURACY ");
  3556.       PUT(X); NEW_LINE;
  3557.     end if;
  3558.  
  3559.     N := INTEGER(Y * ONE_OVER_PI);
  3560.     XN := CONVERT_TO_FLOAT(N);
  3561.     if N mod 2 /= 0  then
  3562.       SGN := -SGN;
  3563.     end if;
  3564.     XN := XN - 0.5;          -- TO FORM COS INSTEAD OF SIN
  3565.     X1 := TRUNCATE(ABS(X));
  3566.     X2 := ABS(X) - X1;
  3567.     F := ((X1 - XN*C1) + X2) - XN*C2;
  3568.     if ABS(F) < EPSILON  then
  3569.       RESULT := F;
  3570.     else
  3571.       G := F * F;
  3572.       RESULT := F + F*R(G);
  3573.     end if;
  3574.     return (SGN * RESULT);
  3575.   end COS;
  3576.  
  3577.  
  3578.   function TAN(X : FLOAT) return FLOAT is
  3579.     SGN, Y : FLOAT;
  3580.     N : INTEGER;
  3581.     XN : FLOAT;
  3582.     F, G, X1, X2 : FLOAT;
  3583.     RESULT : FLOAT;
  3584.  
  3585.     YMAX : FLOAT := FLOAT(INTEGER(PI * TWO**(IT/2))) /2.0;
  3586.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  3587.     EPSILON : FLOAT := BETA ** (-IT/2);
  3588.  
  3589.     C1 : constant FLOAT :=  8#1.444#;
  3590.     C2 : constant FLOAT :=  4.8382_67948_97E-4;
  3591.  
  3592.     function R(G : FLOAT) return FLOAT is
  3593.       P0 : constant FLOAT :=  1.0;
  3594.       P1 : constant FLOAT := -0.11136_14403_566;
  3595.       P2 : constant FLOAT :=  0.10751_54738_488E-2;
  3596.       Q0 : constant FLOAT :=  1.0;
  3597.       Q1 : constant FLOAT := -0.44469_47720_281;
  3598.       Q2 : constant FLOAT :=  0.15973_39213_300E-1;
  3599.     begin
  3600.       return ((P2*G + P1)*G*F + F) / (((Q2*G + Q1)*G +0.5) + 0.5);
  3601.     end R;
  3602.  
  3603.   begin
  3604.     Y := ABS(X);
  3605.     if Y > YMAX  then
  3606.       NEW_LINE;
  3607.       PUT(" TAN CALLED WITH ARGUMENT TOO LARGE FOR ACCURACY ");
  3608.       PUT(X); NEW_LINE;
  3609.     end if;
  3610.  
  3611.     N := INTEGER(X * TWO_OVER_PI);
  3612.     XN := CONVERT_TO_FLOAT(N);
  3613.     X1 := TRUNCATE(X);
  3614.     X2 := X - X1;
  3615.     F := ((X1 - XN*C1) + X2) - XN*C2;
  3616.     if ABS(F) < EPSILON  then
  3617.       RESULT := F;
  3618.     else
  3619.       G := F * F;
  3620.       RESULT := R(G);
  3621.     end if;
  3622.     if N mod 2 = 0  then
  3623.       return RESULT;
  3624.     else
  3625.       return -1.0/RESULT;
  3626.     end if;
  3627.   end TAN;
  3628.  
  3629.   function COT(X : FLOAT) return FLOAT is
  3630.     SGN, Y : FLOAT;
  3631.     N : INTEGER;
  3632.     XN : FLOAT;
  3633.     F, G, X1, X2 : FLOAT;
  3634.     RESULT : FLOAT;
  3635.  
  3636.  
  3637.     YMAX : FLOAT := FLOAT(INTEGER(PI * TWO**(IT/2))) /2.0;
  3638.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  3639.     EPSILON : FLOAT := BETA ** (-IT/2);
  3640.     EPSILON1 : FLOAT :=  1.0/XMAX;
  3641.  
  3642.     C1 : constant FLOAT :=  8#1.444#;
  3643.     C2 : constant FLOAT :=  4.8382_67948_97E-4;
  3644.  
  3645.     function R(G : FLOAT) return FLOAT is
  3646.       P0 : constant FLOAT :=  1.0;
  3647.       P1 : constant FLOAT := -0.11136_14403_566;
  3648.       P2 : constant FLOAT :=  0.10751_54738_488E-2;
  3649.       Q0 : constant FLOAT :=  1.0;
  3650.       Q1 : constant FLOAT := -0.44469_47720_281;
  3651.       Q2 : constant FLOAT :=  0.15973_39213_300E-1;
  3652.     begin
  3653.       return ((P2*G + P1)*G*F + F) / (((Q2*G + Q1)*G +0.5) + 0.5);
  3654.     end R;
  3655.  
  3656.   begin
  3657.     Y := ABS(X);
  3658.     if Y < EPSILON1  then
  3659.       NEW_LINE;
  3660.       PUT(" COT CALLED WITH ARGUMENT TOO NEAR ZERO ");
  3661.       PUT(X); NEW_LINE;
  3662.       if X < 0.0  then
  3663.         return -XMAX;
  3664.       else
  3665.         return XMAX;
  3666.       end if;
  3667.     end if;
  3668.     if Y > YMAX  then
  3669.       NEW_LINE;
  3670.       PUT(" COT CALLED WITH ARGUMENT TOO LARGE FOR ACCURACY ");
  3671.       PUT(X); NEW_LINE;
  3672.     end if;
  3673.  
  3674.     N := INTEGER(X * TWO_OVER_PI);
  3675.     XN := CONVERT_TO_FLOAT(N);
  3676.     X1 := TRUNCATE(X);
  3677.     X2 := X - X1;
  3678.     F := ((X1 - XN*C1) + X2) - XN*C2;
  3679.     if ABS(F) < EPSILON  then
  3680.       RESULT := F;
  3681.     else
  3682.       G := F * F;
  3683.       RESULT := R(G);
  3684.     end if;
  3685.     if N mod 2 /= 0  then
  3686.       return -RESULT;
  3687.     else
  3688.       return 1.0/RESULT;
  3689.     end if;
  3690.   end COT;
  3691.  
  3692.  
  3693.   function ASIN(X : FLOAT) return FLOAT is
  3694.     G, Y : FLOAT;
  3695.     RESULT : FLOAT;
  3696.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  3697.     EPSILON : FLOAT := BETA ** (-IT/2);
  3698.  
  3699.     function R(G : FLOAT) return FLOAT is
  3700.     P1 : constant FLOAT := -0.27516_55529_0596E1;
  3701.     P2 : constant FLOAT :=  0.29058_76237_4859E1;
  3702.     P3 : constant FLOAT := -0.59450_14419_3246;
  3703.     Q0 : constant FLOAT := -0.16509_93320_2424E2;
  3704.     Q1 : constant FLOAT :=  0.24864_72896_9164E2;
  3705.     Q2 : constant FLOAT := -0.10333_86707_2113E2;
  3706.     Q3 : constant FLOAT :=  1.0;
  3707.     begin
  3708.       return (((P3*G + P2)*G + P1)*G) / (((G + Q2)*G + Q1)*G + Q0);
  3709.     end R;
  3710.  
  3711.   begin
  3712.     Y := ABS(X);
  3713.  
  3714.     if Y > HALF  then
  3715.       if Y > 1.0  then
  3716.         NEW_LINE; PUT(" ASIN CALLED FOR "); PUT(X);
  3717.             PUT(" (> 1)  TRUNCATED TO 1, CONTINUED"); NEW_LINE;
  3718.         Y := 1.0;
  3719.       end if;
  3720.       G := ((0.5 - Y) + 0.5) / 2.0;
  3721.       Y := -2.0 * SQRT(G);
  3722.       RESULT := Y + Y * R(G);
  3723.       RESULT := (PI_OVER_FOUR + RESULT) + PI_OVER_FOUR;
  3724.     else
  3725.       if Y < EPSILON  then
  3726.         RESULT := Y;
  3727.       else
  3728.         G := Y * Y;
  3729.         RESULT := Y + Y * R(G);
  3730.       end if;
  3731.     end if;
  3732.     if X < 0.0  then
  3733.       RESULT := -RESULT;
  3734.     end if;
  3735.  
  3736.     return RESULT;
  3737.   end ASIN;
  3738.  
  3739.   function ACOS(X : FLOAT) return FLOAT is
  3740.     G, Y : FLOAT;
  3741.     RESULT : FLOAT;
  3742.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  3743.     EPSILON : FLOAT := BETA ** (-IT/2);
  3744.  
  3745.     function R(G : FLOAT) return FLOAT is
  3746.     P1 : constant FLOAT := -0.27516_55529_0596E1;
  3747.     P2 : constant FLOAT :=  0.29058_76237_4859E1;
  3748.     P3 : constant FLOAT := -0.59450_14419_3246;
  3749.     Q0 : constant FLOAT := -0.16509_93320_2424E2;
  3750.     Q1 : constant FLOAT :=  0.24864_72896_9164E2;
  3751.     Q2 : constant FLOAT := -0.10333_86707_2113E2;
  3752.     Q3 : constant FLOAT :=  1.0;
  3753.     begin
  3754.       return (((P3*G + P2)*G + P1)*G) / (((G + Q2)*G + Q1)*G + Q0);
  3755.     end R;
  3756.  
  3757.   begin
  3758.     Y := ABS(X);
  3759.  
  3760.     if Y > HALF  then
  3761.       if Y > 1.0  then
  3762.         NEW_LINE; PUT(" ACOS CALLED FOR "); PUT(X);
  3763.             PUT(" (> 1)  TRUNCATED TO 1, CONTINUED"); NEW_LINE;
  3764.         Y := 1.0;
  3765.       end if;
  3766.       G := ((0.5 - Y) + 0.5) / 2.0;
  3767.       Y := -2.0 * SQRT(G);
  3768.       RESULT := Y + Y * R(G);
  3769.       if X < 0.0  then
  3770.         RESULT := (PI_OVER_TWO + RESULT) + PI_OVER_TWO;
  3771.       else
  3772.         RESULT := -RESULT;
  3773.       end if;
  3774.  
  3775.     else
  3776.       if Y < EPSILON  then
  3777.         RESULT := Y;
  3778.       else
  3779.         G := Y * Y;
  3780.         RESULT := Y + Y * R(G);
  3781.       end if;
  3782.       if X < 0.0  then
  3783.         RESULT := (PI_OVER_FOUR + RESULT) + PI_OVER_FOUR;
  3784.       else
  3785.         RESULT := (PI_OVER_FOUR - RESULT) + PI_OVER_FOUR;
  3786.       end if;
  3787.     end if;
  3788.  
  3789.     return RESULT;
  3790.   end ACOS;
  3791.  
  3792.  
  3793.   function ATAN(X : FLOAT) return FLOAT is
  3794.     F, G : FLOAT;
  3795.     subtype REGION is INTEGER range 0..3;    --  ##########
  3796.     N : REGION;
  3797.     RESULT : FLOAT;
  3798.  
  3799.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  3800.  
  3801.     EPSILON : FLOAT := BETA ** (-IT/2);
  3802.  
  3803.     SQRT_3           : constant FLOAT :=  1.73205_08075_68877_29353;
  3804.     SQRT_3_MINUS_1   : constant FLOAT :=  0.73205_08075_68877_29353;
  3805.     TWO_MINUS_SQRT_3 : constant FLOAT :=  0.26794_91924_31122_70647;
  3806.  
  3807.     function R(G : FLOAT) return FLOAT is
  3808.       P0 : constant FLOAT := -0.14400_83448_74E1;
  3809.       P1 : constant FLOAT := -0.72002_68488_98;
  3810.       Q0 : constant FLOAT :=  0.43202_50389_19E1;
  3811.       Q1 : constant FLOAT :=  0.47522_25845_99E1;
  3812.       Q2 : constant FLOAT :=  1.0;
  3813.     begin
  3814.       return ((P1*G + P0)*G) / ((G + Q1)*G + Q0);
  3815.     end R;
  3816.  
  3817.   begin
  3818.     F := ABS(X);
  3819.  
  3820.     if F > 1.0  then
  3821.       F := 1.0 / F;
  3822.       N := 2;
  3823.     else
  3824.       N := 0;
  3825.     end if;
  3826.  
  3827.     if F > TWO_MINUS_SQRT_3  then
  3828.       F := (((SQRT_3_MINUS_1 * F - 0.5) - 0.5) + F) / (SQRT_3 + F);
  3829.       N := N + 1;
  3830.     end if;
  3831.  
  3832.     if ABS(F) < EPSILON  then
  3833.       RESULT := F;
  3834.     else
  3835.       G := F * F;
  3836.       RESULT := F + F * R(G);
  3837.     end if;
  3838.  
  3839.     if N > 1  then
  3840.       RESULT := - RESULT;
  3841.     end if;
  3842.  
  3843.     case N is
  3844.     when 0  =>
  3845.       RESULT := RESULT;
  3846.     when 1  =>
  3847.       RESULT := PI_OVER_SIX + RESULT;
  3848.     when 2  =>
  3849.       RESULT := PI_OVER_TWO + RESULT;
  3850.     when 3  =>
  3851.       RESULT := PI_OVER_THREE + RESULT;
  3852.     end case;
  3853.  
  3854.     if X < 0.0  then
  3855.       RESULT := - RESULT;
  3856.     end if;
  3857.  
  3858.     return RESULT;
  3859.  
  3860.   end ATAN;
  3861.  
  3862.  
  3863.  
  3864.   function ATAN2(V, U : FLOAT) return FLOAT is
  3865.     X, RESULT : FLOAT;
  3866.  
  3867.   begin
  3868.  
  3869.     if U = 0.0  then
  3870.       if V = 0.0  then
  3871.         RESULT := 0.0;
  3872.         NEW_LINE;
  3873.         PUT(" ATAN2 CALLED WITH 0/0   RETURNED "); PUT(RESULT);
  3874.         NEW_LINE;
  3875.       elsif V > 0.0  then
  3876.         RESULT := PI_OVER_TWO;
  3877.       else
  3878.         RESULT := - PI_OVER_TWO;
  3879.       end if;
  3880.  
  3881.     else
  3882.       X := ABS(V/U);
  3883.       --  If underflow or overflow is detected, go to the exception
  3884.       RESULT := ATAN(X);
  3885.       if U < 0.0  then
  3886.         RESULT := PI - RESULT;
  3887.       end if;
  3888.       if V < 0.0  then
  3889.         RESULT := - RESULT;
  3890.       end if;
  3891.     end if;
  3892.     return RESULT;
  3893.   exception
  3894.   when NUMERIC_ERROR  =>
  3895.     if ABS(V) > ABS(U)  then
  3896.       RESULT := PI_OVER_TWO;
  3897.       if V < 0.0  then
  3898.         RESULT := - RESULT;
  3899.       end if;
  3900.     else
  3901.       RESULT := 0.0;
  3902.       if U < 0.0  then
  3903.         RESULT := PI - RESULT;
  3904.       end if;
  3905.     end if;
  3906.     return RESULT;
  3907.   end ATAN2;
  3908.  
  3909.  
  3910.   function SINH(X : FLOAT) return FLOAT is
  3911.     G, W, Y, Z : FLOAT;
  3912.     RESULT : FLOAT;
  3913.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  3914.     EPSILON : FLOAT := BETA ** (-IT/2);
  3915.  
  3916.     YBAR : FLOAT := EXP_LARGE;
  3917.     LN_V : FLOAT := 8#0.542714#;
  3918.     V_OVER_2_MINUS_1 : FLOAT :=  0.13830_27787_96019_02638E-4;
  3919.     WMAX : FLOAT := YBAR - LN_V + 0.69;
  3920.  
  3921.     function R(G : FLOAT) return FLOAT is
  3922.     P0 : constant FLOAT :=  0.10622_28883_7151E4;
  3923.     P1 : constant FLOAT :=  0.31359_75645_6058E2;
  3924.     P2 : constant FLOAT :=  0.34364_14035_8506;
  3925.     Q0 : constant FLOAT :=  0.63733_73302_1822E4;
  3926.     Q1 : constant FLOAT := -0.13051_01250_9199E3;
  3927.     Q2 : constant FLOAT :=  1.0;
  3928.     begin
  3929.       return (((P2*G + P1)*G + P0)*G) / ((G + Q1)*G + Q0);
  3930.     end R;
  3931.  
  3932.   begin
  3933.     Y := ABS(X);
  3934.  
  3935.     if Y <= 1.0  then
  3936.       if Y < EPSILON  then
  3937.         RESULT := X;
  3938.       else
  3939.         G := X * X;
  3940.         RESULT := X + X * R(G);
  3941.       end if;
  3942.  
  3943.     else
  3944.       if Y <= YBAR  then
  3945.         Z := EXP(Y);
  3946.         RESULT := (Z - 1.0/Z) / 2.0;
  3947.       else
  3948.         W := Y - LN_V;
  3949.         if W > WMAX  then
  3950.           NEW_LINE;
  3951.           PUT(" SINH CALLED WITH TOO LARGE ARGUMENT  "); PUT(X);
  3952.           PUT(" RETURN BIG"); NEW_LINE;
  3953.           W := WMAX;
  3954.         end if;
  3955.         Z := EXP(W);
  3956.         RESULT := Z + V_OVER_2_MINUS_1 * Z;
  3957.       end if;
  3958.       if X < 0.0  then
  3959.         RESULT := -RESULT;
  3960.       end if;
  3961.  
  3962.     end if;
  3963.     return RESULT;
  3964.   end SINH;
  3965.  
  3966.  
  3967.   function COSH(X : FLOAT) return FLOAT is
  3968.     G, W, Y, Z : FLOAT;
  3969.     RESULT : FLOAT;
  3970.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  3971.     EPSILON : FLOAT := BETA ** (-IT/2);
  3972.  
  3973.     YBAR : FLOAT := EXP_LARGE;
  3974.     LN_V : FLOAT := 8#0.542714#;
  3975.     V_OVER_2_MINUS_1 : FLOAT :=  0.13830_27787_96019_02638E-4;
  3976.     WMAX : FLOAT := YBAR - LN_V + 0.69;
  3977.  
  3978.     function R(G : FLOAT) return FLOAT is
  3979.     P0 : constant FLOAT :=  0.10622_28883_7151E4;
  3980.     P1 : constant FLOAT :=  0.31359_75645_6058E2;
  3981.     P2 : constant FLOAT :=  0.34364_14035_8506;
  3982.     Q0 : constant FLOAT :=  0.63733_73302_1822E4;
  3983.     Q1 : constant FLOAT := -0.13051_01250_9199E3;
  3984.     Q2 : constant FLOAT :=  1.0;
  3985.     begin
  3986.       return (((P2*G + P1)*G + P0)*G) / ((G + Q1)*G + Q0);
  3987.     end R;
  3988.  
  3989.   begin
  3990.     Y := ABS(X);
  3991.  
  3992.     if Y <= YBAR  then
  3993.       Z := EXP(Y);
  3994.       RESULT := (Z + 1.0/Z) / 2.0;
  3995.     else
  3996.       W := Y - LN_V;
  3997.       if W > WMAX  then
  3998.         NEW_LINE;
  3999.         PUT(" COSH CALLED WITH TOO LARGE ARGUMENT  "); PUT(X);
  4000.         PUT(" RETURN BIG"); NEW_LINE;
  4001.         W := WMAX;
  4002.       end if;
  4003.       Z := EXP(W);
  4004.       RESULT := Z + V_OVER_2_MINUS_1 * Z;
  4005.     end if;
  4006.  
  4007.     return RESULT;
  4008.   end COSH;
  4009.  
  4010.  
  4011.   function TANH(X : FLOAT) return FLOAT is
  4012.     G, W, Y, Z : FLOAT;
  4013.     RESULT : FLOAT;
  4014.     BETA : FLOAT := CONVERT_TO_FLOAT(IBETA);
  4015.     EPSILON : FLOAT := BETA ** (-IT/2);
  4016.  
  4017.     XBIG : FLOAT := (LOG(2.0) + CONVERT_TO_FLOAT(IT + 1) * LOG(BETA))/2.0;
  4018.     LN_3_OVER_2 : FLOAT :=  0.54930_61443_34054_84570;
  4019.  
  4020.     function R(G : FLOAT) return FLOAT is
  4021.     P0 : constant FLOAT := -0.21063_95800_0245E2;
  4022.     P1 : constant FLOAT := -0.93363_47565_2401;
  4023.     Q0 : constant FLOAT :=  0.63191_87401_5582E2;
  4024.     Q1 : constant FLOAT :=  0.28077_65347_0471E2;
  4025.     Q2 : constant FLOAT :=  1.0;
  4026.     begin
  4027.       return ((P1*G + P0)*G) / ((G + Q1)*G + Q0);
  4028.     end R;
  4029.  
  4030.   begin
  4031.     Y := ABS(X);
  4032.  
  4033.     if Y > XBIG  then
  4034.       RESULT := 1.0;
  4035.     else
  4036.       if Y > LN_3_OVER_2  then
  4037.         RESULT := 0.5 - 1.0 / (EXP(Y + Y) + 1.0);
  4038.         RESULT := RESULT + RESULT;
  4039.       else
  4040.         if Y < EPSILON  then
  4041.           RESULT := Y;
  4042.         else
  4043.           G := Y * Y;
  4044.           RESULT := Y + Y * R(G);
  4045.         end if;
  4046.       end if;
  4047.     end if;
  4048.     if X < 0.0  then
  4049.       RESULT := - RESULT;
  4050.     end if;
  4051.  
  4052.     return RESULT;
  4053.   end TANH;
  4054.  
  4055.  
  4056. begin
  4057.   null;
  4058. end TRIG_LIB;
  4059. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4060. --floatch.txt
  4061. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4062. with TEXT_IO; use TEXT_IO;
  4063. package body FLOATING_CHARACTERISTICS is
  4064. --  This package is a floating mantissa definition of a binary FLOAT
  4065.  
  4066.     A, B, Y, Z : FLOAT;
  4067.     I, K, MX, IZ : INTEGER;
  4068.     BETA, BETAM1, BETAIN : FLOAT;
  4069.     ONE : FLOAT := 1.0;
  4070.     ZERO : FLOAT := 0.0;
  4071.  
  4072.   procedure DEFLOAT(X : in FLOAT;
  4073.                     N : out EXPONENT_TYPE; F : out MANTISSA_TYPE) is
  4074. --  This is admittedly a slow method - but portable - for breaking down
  4075. --  a floating point number into its exponent and mantissa
  4076. --  Obviously with knowledge of the machine representation
  4077. --  it could be replaced with a couple of simple extractions
  4078.     EXPONENT_LENGTH : INTEGER := IEXP;
  4079.     Q : MANTISSA_TYPE;
  4080.     M, L : EXPONENT_TYPE;
  4081.     W, Y, Z : FLOAT;
  4082.   begin
  4083.     L := 0;
  4084.     Q := 0.0;
  4085.     Y := ABS(X);
  4086.     if Y = 0.0  then
  4087.       return;
  4088.     elsif Y < 0.5  then
  4089.       for J in reverse 0..(EXPONENT_LENGTH - 2)  loop
  4090.       --  Dont want to go all the way to 2.0**(EXPONENT_LENGTH - 1)
  4091.       --  Since that (or its reciprocal) will overflow if exponent biased
  4092.       --  Ought to use talbular values rather than compute each time
  4093.         M := EXPONENT_TYPE(2 ** J);
  4094.         Z := 1.0 / (2.0**M);
  4095.         W := Y / Z;
  4096.         if W < 1.0  then
  4097.           Y := W;
  4098.           L := L - M;
  4099.         end if;
  4100.       end loop;
  4101.     else
  4102.       for J in reverse 0..(EXPONENT_LENGTH - 2)  loop
  4103.         M := EXPONENT_TYPE(2 ** J);
  4104.         Z := 2.0**M;
  4105.         W := Y / Z;
  4106.         if W >= 0.5  then
  4107.           Y := W;
  4108.           L := L + M;
  4109.         end if;
  4110.       end loop;
  4111.     --  And just to clear up any loose ends from biased exponents
  4112.     end if;
  4113.     while Y < 0.5  loop
  4114.       Y := Y * 2.0;
  4115.       L := L - 1;
  4116.     end loop;
  4117.     while Y >= 1.0  loop
  4118.       Y := Y / 2.0;
  4119.       L := L + 1;
  4120.     end loop;
  4121.     Q := MANTISSA_TYPE(Y);
  4122.     if X < 0.0  then
  4123.       Q := -Q;
  4124.     end if;
  4125.     N := L;
  4126.     F := Q;
  4127.     return;
  4128.   exception
  4129.   when others =>
  4130.     N := 0;
  4131.     F := 0.0;
  4132.     return;
  4133.   end DEFLOAT;
  4134.  
  4135.  
  4136.   procedure REFLOAT(N : in EXPONENT_TYPE; F : in MANTISSA_TYPE; 
  4137.                                                    X : out FLOAT) is
  4138. --  Again a brute force method - but portable
  4139. --  Watch out near MAXEXP
  4140.     M : INTEGER;
  4141.     Y, Z : FLOAT;
  4142.   begin
  4143.     if F = 0.0  then
  4144.       Z := ZERO;
  4145.       X := Z;
  4146.       return;
  4147.     end if;
  4148.     M := INTEGER(N);
  4149.     Y := ABS(FLOAT(F));
  4150.     while Y < 0.5  loop
  4151.       M := M - 1;
  4152.       if M < MINEXP  then
  4153.         Z := ZERO;
  4154.         X := Z;
  4155.       end if;
  4156.       Y := Y + Y;
  4157.       exit when M <= MINEXP;
  4158.     end loop;
  4159.     if M = MAXEXP  then
  4160.       M := M - 1;
  4161.       Z := Y * 2.0**M;
  4162.       Z := Z * 2.0;
  4163.       X := Z;
  4164.     elsif M <= MINEXP + 2  then
  4165.       M := M + 3;
  4166.       Z := Y * 2.0**M;
  4167.       Z := ((Z / 2.0) / 2.0) / 2.0;
  4168.       X := Z;
  4169.     else
  4170.       Z := Y * 2.0**M;
  4171.       X := Z;
  4172.     end if;
  4173.     if F < 0.0  then
  4174.       Z := -Z;
  4175.       X := Z;
  4176.     end if;
  4177.     return;
  4178.   end REFLOAT;
  4179.  
  4180.   function CONVERT_TO_FLOAT(K : INTEGER) return FLOAT is
  4181.   begin
  4182.     return FLOAT(K);
  4183.   end CONVERT_TO_FLOAT;
  4184.  
  4185. --  function CONVERT_TO_FLOAT(N : EXPONENT_TYPE) return FLOAT is
  4186. --  begin
  4187. --    return FLOAT(N);
  4188. --  end CONVERT_TO_FLOAT;
  4189.  
  4190.   function CONVERT_TO_FLOAT(F : MANTISSA_TYPE) return FLOAT is
  4191.   begin
  4192.     return FLOAT(F);
  4193.   end CONVERT_TO_FLOAT;
  4194.  
  4195.  
  4196. begin
  4197.  
  4198.   PUT_LINE ( "BEGIN INITIALIZATION" );
  4199.   IBETA := 2;
  4200.   IT := 23;
  4201.   IRND := 0;
  4202.   NGRD := 0;
  4203.   NEGEP := -24;
  4204.   MACHEP := -24;
  4205.   EPSNEG := FLOAT(IBETA) ** MACHEP;
  4206.   EPS := EPSNEG;
  4207.   MINEXP := -126;
  4208.   IEXP := 8;
  4209.   MAXEXP := 126;
  4210.   XMIN := FLOAT(IBETA) ** MINEXP;
  4211.   XMAX := FLOAT(IBETA) ** MAXEXP;
  4212.   PUT_LINE ("INITIALIZED"); NEW_LINE;
  4213.  
  4214. end FLOATING_CHARACTERISTICS;
  4215. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4216. --coref.txt
  4217. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4218. with TEXT_IO; use TEXT_IO;
  4219. with FLOATING_CHARACTERISTICS; use FLOATING_CHARACTERISTICS;
  4220. with NUMERIC_PRIMITIVES; use NUMERIC_PRIMITIVES;
  4221. package body CORE_FUNCTIONS is
  4222.  
  4223.   package FLT_IO is new FLOAT_IO ( FLOAT );
  4224.   package INT_IO is new INTEGER_IO ( INTEGER );
  4225.   use FLT_IO, INT_IO;
  4226.  
  4227. --  The following routines are coded directly from the algorithms and
  4228. --  coeficients given in "Software Manual for the Elementry Functions"
  4229. --  by William J. Cody, Jr. and William Waite, Prentice_Hall, 1980
  4230. --  CBRT by analogy
  4231. --  A more general formulation uses MANTISSA_TYPE, etc.
  4232. --  The coeficients are appropriate for 25 to 32 bits floating significance
  4233. --  They will work for less but slightly shorter versions are possible
  4234. --  The routines are coded to stand alone so they need not be compiled together
  4235.  
  4236. --  These routines have been coded to accept a general MANTISSA_TYPE
  4237. --  That is, they are designed to work with a manitssa either fixed of float
  4238. --  There are some explicit conversions which are required but these will
  4239. --  not cause any extra code to be generated
  4240.  
  4241. --      16 JULY 1982       W A WHITAKER  AFATL EGLIN AFB FL 32542
  4242. --                         T C EICHOLTZ  USAFA
  4243.  
  4244.  
  4245.   function SQRT(X : FLOAT) return FLOAT is
  4246.     M, N : EXPONENT_TYPE;
  4247.     F, Y : MANTISSA_TYPE;
  4248.     RESULT : FLOAT;
  4249.  
  4250.     subtype INDEX is INTEGER range 0..100;    --  #########################
  4251.     SQRT_L1 : INDEX := 3;
  4252.     --  Could get away with SQRT_L1 := 2 for 28 bits
  4253.     --  Using the better Cody-Waite coeficients overflows MANTISSA_TYPE
  4254.     SQRT_C1 : MANTISSA_TYPE := 8#0.3317777777#;
  4255.     SQRT_C2 : MANTISSA_TYPE := 8#0.4460000000#;
  4256.     SQRT_C3 : MANTISSA_TYPE := 8#0.55202_36314_77747_36311_0#;
  4257.  
  4258.   begin
  4259.     if X = ZERO  then
  4260.       RESULT := ZERO;
  4261.       return RESULT;
  4262.     elsif X = ONE  then            --  To get exact SQRT(1.0)
  4263.       RESULT := ONE;
  4264.       return RESULT;
  4265.     elsif X < ZERO  then
  4266.       NEW_LINE;
  4267.       PUT("CALLED SQRT FOR NEGATIVE ARGUMENT   ");
  4268.       PUT(X);
  4269.       PUT("   USED ABSOLUTE VALUE");
  4270.       NEW_LINE;
  4271.       RESULT := SQRT(ABS(X));
  4272.       return RESULT;
  4273.     else
  4274.       DEFLOAT(X, N, F);
  4275.       Y := SQRT_C1 + MANTISSA_TYPE(SQRT_C2 * F);
  4276.       for J in 1..SQRT_L1  loop
  4277.         Y := Y/MANTISSA_DIVISOR_2 + MANTISSA_TYPE((F/MANTISSA_DIVISOR_2)/Y);
  4278.       end loop;
  4279.       if (N mod 2) /= 0  then
  4280.         Y := MANTISSA_TYPE(SQRT_C3 * Y);
  4281.         N := N + 1;
  4282.       end if;
  4283.       M := N/2;
  4284.       REFLOAT(M,Y,RESULT);
  4285.       return RESULT;
  4286.     end if;
  4287.   exception
  4288.   when others =>
  4289.     NEW_LINE; PUT(" EXCEPTION IN SQRT, X = "); PUT(X);
  4290.     PUT("  RETURNED 1.0"); NEW_LINE;
  4291.     return ONE;
  4292.   end SQRT;
  4293.  
  4294.  
  4295.   function CBRT(X : FLOAT) return FLOAT is
  4296.     M, N : EXPONENT_TYPE;
  4297.     F, Y : MANTISSA_TYPE;
  4298.     RESULT : FLOAT;
  4299.  
  4300.     subtype INDEX is INTEGER range 0..100;    --  #########################
  4301.     CBRT_L1 : INDEX := 3;
  4302.     CBRT_C1 : MANTISSA_TYPE := 0.5874009;
  4303.     CBRT_C2 : MANTISSA_TYPE := 0.4125990;
  4304.     CBRT_C3 : MANTISSA_TYPE := 0.62996_05249;
  4305.     CBRT_C4 : MANTISSA_TYPE := 0.79370_05260;
  4306.  
  4307.   begin
  4308.     if X = ZERO then
  4309.       RESULT := ZERO;
  4310.       return RESULT;
  4311.     else
  4312.       DEFLOAT(X, N, F);
  4313.       F := ABS(F);
  4314.       Y := CBRT_C1 + MANTISSA_TYPE(CBRT_C2 * F);
  4315.       for J in 1 .. CBRT_L1 loop
  4316.         Y :=     Y
  4317.             - (  Y/MANTISSA_DIVISOR_3 
  4318.                - MANTISSA_TYPE((F/MANTISSA_DIVISOR_3) / MANTISSA_TYPE(Y*Y)) );
  4319.       end loop;
  4320.       case (N mod 3) is
  4321.         when 0 =>
  4322.           null;
  4323.         when 1 =>
  4324.           Y := MANTISSA_TYPE(CBRT_C3 * Y);
  4325.           N := N + 2;
  4326.         when 2 =>
  4327.           Y := MANTISSA_TYPE(CBRT_C4 * Y);
  4328.           N := N + 1;
  4329.         when others =>
  4330.           null;
  4331.       end case;
  4332.       M := N/3;
  4333.       if X < ZERO  then
  4334.         Y := -Y;
  4335.       end if;
  4336.       REFLOAT(M, Y, RESULT);
  4337.       return RESULT;
  4338.     end if;
  4339.   exception
  4340.     when others =>
  4341.       RESULT := ONE;
  4342.       if X < ZERO then
  4343.       RESULT := - ONE;
  4344.       end if;
  4345.       NEW_LINE; PUT("EXCEPTION IN CBRT, X = "); PUT(X);
  4346.       PUT("  RETURNED  "); PUT(RESULT); NEW_LINE;
  4347.       return RESULT;
  4348.   end CBRT;
  4349.  
  4350.     function LOG(X : FLOAT) return FLOAT is
  4351.   --  Uses fixed formulation for generality
  4352.  
  4353.     RESULT : FLOAT;
  4354.     N : EXPONENT_TYPE;
  4355.     XN : FLOAT;
  4356.     Y : FLOAT;
  4357.     F : MANTISSA_TYPE;
  4358.     Z, ZDEN, ZNUM : MANTISSA_TYPE;
  4359.  
  4360.     C0 : constant MANTISSA_TYPE := 0.20710_67811_86547_52440;
  4361.                                                --  SQRT(0.5) - 0.5
  4362.     C1 : constant FLOAT := 8#0.543#;
  4363.     C2 : constant FLOAT :=-2.12194_44005_46905_82767_9E-4;
  4364.  
  4365.     function R(Z : MANTISSA_TYPE) return MANTISSA_TYPE is
  4366.     --  Use fixed formulation here because the float coeficents are > 1.0
  4367.     --  and would exceed the limits on a MANTISSA_TYPE
  4368.       A0 : constant MANTISSA_TYPE := 0.04862_85276_587;
  4369.       B0 : constant MANTISSA_TYPE := 0.69735_92187_803;
  4370.       B1 : constant MANTISSA_TYPE :=-0.125;
  4371.       C  : constant MANTISSA_TYPE := 0.01360_09546_862;
  4372.     begin
  4373.       return Z + MANTISSA_TYPE(Z * 
  4374.           MANTISSA_TYPE(MANTISSA_TYPE(Z * Z) * (C +
  4375.           MANTISSA_TYPE(A0/(B0 + MANTISSA_TYPE(B1 * MANTISSA_TYPE(Z * Z)))))));
  4376.     end R;
  4377.  
  4378.   begin
  4379.  
  4380.     if X < ZERO      then
  4381.       NEW_LINE;
  4382.       PUT("CALLED LOG FOR NEGATIVE ");
  4383.       PUT(X);
  4384.       PUT("   USE ABS => ");
  4385.       RESULT := LOG(ABS(X));
  4386.       PUT(RESULT);
  4387.       NEW_LINE;
  4388.     elsif X = ZERO  then
  4389.       NEW_LINE;
  4390.       PUT("CALLED LOG FOR ZERO ARGUMENT, RETURNED ");
  4391.       RESULT := -XMAX;      --  SUPPOSED TO BE -LARGE
  4392.       PUT(RESULT);
  4393.       NEW_LINE;
  4394.     else
  4395.       DEFLOAT(X,N,F);
  4396.       ZNUM := F - MANTISSA_HALF;
  4397.       Y := CONVERT_TO_FLOAT(ZNUM);
  4398.       ZDEN := ZNUM / MANTISSA_DIVISOR_2 + MANTISSA_HALF;
  4399.       if ZNUM > C0  then
  4400.         Y := Y - MANTISSA_HALF;
  4401.         ZNUM := ZNUM - MANTISSA_HALF;
  4402.         ZDEN := ZDEN + MANTISSA_HALF/MANTISSA_DIVISOR_2;
  4403.       else
  4404.         N := N -1;
  4405.       end if;
  4406.       Z    := MANTISSA_TYPE(ZNUM / ZDEN);
  4407.       RESULT := CONVERT_TO_FLOAT(R(Z));
  4408.       if N /= 0  then
  4409.         XN := CONVERT_TO_FLOAT(N);
  4410.         RESULT := (XN * C2 + RESULT) + XN * C1;
  4411.       end if;
  4412.     end if;
  4413.     return RESULT;
  4414.  
  4415.   exception
  4416.   when others =>
  4417.     NEW_LINE; PUT(" EXCEPTION IN LOG, X = "); PUT(X);
  4418.     PUT("  RETURNED 0.0"); NEW_LINE;
  4419.     return ZERO;
  4420.   end LOG;
  4421.  
  4422.  
  4423.   function LOG10(X : FLOAT) return FLOAT is
  4424.     LOG_10_OF_2 : constant FLOAT :=
  4425.              CONVERT_TO_FLOAT(MANTISSA_TYPE(8#0.33626_75425_11562_41615#));
  4426.   begin
  4427.     return LOG(X) * LOG_10_OF_2;
  4428.   end LOG10;
  4429.  
  4430.   function EXP(X : FLOAT) return FLOAT is
  4431.  
  4432.     RESULT : FLOAT;
  4433.     N : EXPONENT_TYPE;
  4434.     XG, XN, X1, X2 : FLOAT;
  4435.     F, G : MANTISSA_TYPE;
  4436.  
  4437.     BIGX : FLOAT := EXP_LARGE;
  4438.     SMALLX : FLOAT := EXP_SMALL;
  4439.  
  4440.     ONE_OVER_LOG_2 : constant FLOAT :=  1.4426_95040_88896_34074;
  4441.     C1 : constant FLOAT :=  0.69335_9375;
  4442.     C2 : constant FLOAT := -2.1219_44400_54690_58277E-4;
  4443.  
  4444.     function R(G : MANTISSA_TYPE) return MANTISSA_TYPE is
  4445.       Z , GP, Q : MANTISSA_TYPE;
  4446.  
  4447.       P0 : constant MANTISSA_TYPE :=  0.24999_99999_9992;
  4448.       P1 : constant MANTISSA_TYPE :=  0.00595_04254_9776;
  4449.       Q0 : constant MANTISSA_TYPE :=  0.5;
  4450.       Q1 : constant MANTISSA_TYPE :=  0.05356_75176_4522;
  4451.       Q2 : constant MANTISSA_TYPE :=  0.00029_72936_3682;
  4452.     begin
  4453.       Z  := MANTISSA_TYPE(G * G);
  4454.       GP := MANTISSA_TYPE( (MANTISSA_TYPE(P1 * Z) + P0) * G );
  4455.       Q  := MANTISSA_TYPE( (MANTISSA_TYPE(Q2 * Z) + Q1) * Z ) + Q0;
  4456.       return MANTISSA_HALF + MANTISSA_TYPE( GP /(Q - GP) );
  4457.     end R;
  4458.  
  4459.  
  4460.   begin
  4461.  
  4462.     if X > BIGX  then
  4463.       NEW_LINE;
  4464.       PUT("  EXP CALLED WITH TOO BIG A POSITIVE ARGUMENT, ");
  4465.           PUT(X); PUT("   RETURNED XMAX");
  4466.       NEW_LINE;
  4467.       RESULT := XMAX;
  4468.     elsif X < SMALLX  then
  4469.       NEW_LINE;
  4470.       PUT("  EXP CALLED WITH TOO BIG A NEGATIVE ARGUMENT,  ");
  4471.           PUT(X); PUT("    RETURNED ZERO");
  4472.       NEW_LINE;
  4473.       RESULT := ZERO;
  4474.     elsif ABS(X) < EPS  then
  4475.       RESULT := ONE;
  4476.     else
  4477.       N  := EXPONENT_TYPE(X * ONE_OVER_LOG_2);
  4478.       XN := CONVERT_TO_FLOAT(N);
  4479.       X1 := ROUND(X);
  4480.       X2 := X - X1;
  4481.       XG := ( (X1 - XN * C1) + X2 ) - XN * C2;
  4482.       G  := MANTISSA_TYPE(XG);
  4483.       N  := N + 1;
  4484.       F := R(G);
  4485.       REFLOAT(N, F, RESULT);
  4486.     end if;
  4487.     return RESULT;
  4488.  
  4489.   exception
  4490.   when others =>
  4491.     NEW_LINE; PUT(" EXCEPTION IN EXP, X = "); PUT(X);
  4492.     PUT("  RETURNED 1.0"); NEW_LINE;
  4493.     return ONE;
  4494.   end EXP;
  4495.  
  4496. function "**" (X, Y : FLOAT) return FLOAT is
  4497. --  This is the last function to be coded since it appeared that it really
  4498. --  was un-Ada-like and ought not be in the regular package
  4499. --  Nevertheless it was included in this version
  4500. --  It is specific for FLOAT and does not have the MANTISSA_TYPE generality
  4501.   M, N : EXPONENT_TYPE;
  4502.   G : MANTISSA_TYPE;
  4503.   P, TEMP, IW1, I : INTEGER;
  4504.   RESULT, Z, V, R, U1, U2, W, W1, W2, W3, Y1, Y2 : FLOAT;
  4505.  
  4506.   K : constant FLOAT := 0.44269_50408_88963_40736;
  4507.   IBIGX : constant INTEGER := INTEGER(TRUNCATE(16.0 * LOG(XMAX) - 1.0));
  4508.   ISMALLX : constant INTEGER := INTEGER(TRUNCATE(16.0 * LOG(XMIN) + 1.0));
  4509.  
  4510.   P1 : constant FLOAT := 0.83333_32862_45E-1;
  4511.   P2 : constant FLOAT := 0.12506_48500_52E-1;
  4512.  
  4513.   Q1 : constant FLOAT := 0.69314_71805_56341;
  4514.   Q2 : constant FLOAT := 0.24022_65061_44710;
  4515.   Q3 : constant FLOAT := 0.55504_04881_30765E-1;
  4516.   Q4 : constant FLOAT := 0.96162_06595_83789E-2;
  4517.   Q5 : constant FLOAT := 0.13052_55159_42810E-2;
  4518.  
  4519.   A1 : array (1 .. 17) of FLOAT:=
  4520.      (  8#1.00000_0000#,        
  4521.         8#0.75222_5750#,        
  4522.         8#0.72540_3067#,        
  4523.         8#0.70146_3367#,        
  4524.         8#0.65642_3746#,        
  4525.         8#0.63422_2140#,        
  4526.         8#0.61263_4520#,        
  4527.         8#0.57204_2434#,        
  4528.         8#0.55202_3631#,        
  4529.         8#0.53254_0767#,        
  4530.         8#0.51377_3265#,        
  4531.         8#0.47572_4623#,        
  4532.         8#0.46033_7602#,        
  4533.         8#0.44341_7233#,        
  4534.         8#0.42712_7017#,        
  4535.         8#0.41325_3033#,        
  4536.         8#0.40000_0000#  );        
  4537.                 
  4538.   A2 : array (1 .. 8) of FLOAT :=
  4539.      (  8#0.00000_00005_22220_66302_61734_72062#,
  4540.         8#0.00000_00003_02522_47021_04062_61124#,
  4541.         8#0.00000_00005_21760_44016_17421_53016#,
  4542.         8#0.00000_00007_65401_41553_72504_02177#,
  4543.         8#0.00000_00002_44124_12254_31114_01243#,
  4544.         8#0.00000_00000_11064_10432_66404_42174#,
  4545.         8#0.00000_00004_72542_16063_30176_55544#,
  4546.         8#0.00000_00001_74611_03661_23056_22556#  );
  4547.        
  4548.  
  4549.   function REDUCE (V : FLOAT) return FLOAT is
  4550.   begin
  4551.     return FLOAT(INTEGER(16.0 * V)) * 0.0625;
  4552.   end REDUCE;
  4553.  
  4554.   begin
  4555.     if X <= ZERO then
  4556.       if X < ZERO then
  4557.         RESULT := (ABS(X))**Y;
  4558.         NEW_LINE;
  4559.         PUT("X**Y CALLED WITH X = "); PUT(X); NEW_LINE;
  4560.         PUT("USED ABS, RETURNED "); PUT(RESULT); NEW_LINE;
  4561.       else
  4562.         if Y <= ZERO then
  4563.           if Y = ZERO then
  4564.             RESULT := ZERO;
  4565.           else
  4566.             RESULT := XMAX;
  4567.           end if;
  4568.           NEW_LINE;
  4569.           PUT("X**Y CALLED WITH X = 0, Y = "); PUT(Y); NEW_LINE;
  4570.           PUT("RETURNED "); PUT(RESULT); NEW_LINE;
  4571.         else
  4572.           RESULT := ZERO;
  4573.         end if;
  4574.       end if;
  4575.     else
  4576.       DEFLOAT(X, M, G);
  4577.       P := 1;
  4578.       if G <= A1(9) then
  4579.         P := 9;
  4580.       end if;
  4581.       if G <= A1(P+4) then
  4582.         P := P + 4;
  4583.       end if;
  4584.       if G <= A1(P+2) then
  4585.         P := P + 2;
  4586.       end if;
  4587.       Z := ((G - A1(P+1)) - A2((P+1)/2))/(G + A1(P+1));
  4588.       Z := Z + Z;
  4589.       V := Z * Z;
  4590.       R := (P2 * V + P1) * V * Z;
  4591.       R := R + K * R;
  4592.       U2 := (R + Z * K) + Z;
  4593.       U1 := FLOAT(INTEGER(M) * 16 - P) * 0.0625;
  4594.       Y1 := REDUCE(Y);
  4595.       Y2 := Y - Y1;
  4596.       W := U2 * Y + U1 * Y2;
  4597.       W1 := REDUCE(W);
  4598.       W2 := W - W1;
  4599.       W := W1 + U1 * Y1;
  4600.       W1 := REDUCE(W);
  4601.       W2 := W2 + (W - W1);
  4602.       W3 := REDUCE(W2);
  4603.       IW1 := INTEGER(TRUNCATE(16.0 * (W1 + W3)));
  4604.       W2 := W2 - W3;
  4605.       if W > FLOAT(IBIGX) then
  4606.         RESULT := XMAX;
  4607.         PUT("X**Y CALLED  X ="); PUT(X); PUT("   Y ="); PUT(Y);
  4608.         PUT("   TOO LARGE  RETURNED "); PUT(RESULT); NEW_LINE;
  4609.       elsif W < FLOAT(ISMALLX) then
  4610.         RESULT := ZERO;
  4611.         PUT("X**Y CALLED  X ="); PUT(X); PUT("   Y ="); PUT(Y);
  4612.         PUT("   TOO SMALL  RETURNED "); PUT(RESULT); NEW_LINE;
  4613.       else
  4614.         if W2 > ZERO then
  4615.           W2 := W2 - 0.0625;
  4616.           IW1 := IW1 + 1;
  4617.         end if;
  4618.         if IW1 < INTEGER(ZERO) then
  4619.           I := 0;
  4620.         else 
  4621.           I := 1;
  4622.         end if;
  4623.         M := EXPONENT_TYPE(I + IW1/16);
  4624.         P := 16 * INTEGER(M) - IW1;
  4625.         Z := ((((Q5 * W2 + Q4) * W2 + Q3) * W2 + Q2) * W2 + Q1) * W2;
  4626.         Z := A1(P+1) + (A1(P+1) * Z);  
  4627.  
  4628.         REFLOAT(M, Z, RESULT);
  4629.       end if;
  4630.     end if;
  4631.     return RESULT;
  4632.   end "**";
  4633.  
  4634. begin
  4635.   EXP_LARGE := LOG(XMAX) * (ONE - EPS);
  4636.   EXP_SMALL := LOG(XMIN) * (ONE - EPS);
  4637. end CORE_FUNCTIONS;
  4638. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4639. --numpr.txt
  4640. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4641. with FLOATING_CHARACTERISTICS; use FLOATING_CHARACTERISTICS;
  4642. package body NUMERIC_PRIMITIVES is
  4643.  
  4644.  
  4645.   function SIGN(X, Y : FLOAT) return FLOAT is
  4646.     --  Returns the value of X with the sign of Y
  4647.   begin
  4648.     if Y >= 0.0  then
  4649.       return X;
  4650.     else
  4651.       return -X;
  4652.     end if;
  4653.   end SIGN;
  4654.  
  4655.   function MAX(X, Y : FLOAT) return FLOAT is
  4656.   begin
  4657.     if X >= Y  then
  4658.       return X;
  4659.     else
  4660.       return Y;
  4661.     end if;
  4662.   end MAX;
  4663.  
  4664.   function TRUNCATE(X : FLOAT) return FLOAT is
  4665.   --  Optimum code depends on how the system rounds at exact halves
  4666.   begin
  4667.     if FLOAT(INTEGER(X)) = X  then
  4668.       return X;
  4669.     end if;
  4670.     if X > ZERO  then
  4671.       return FLOAT(INTEGER(X - HALF));
  4672.     elsif X = ZERO  then
  4673.       return ZERO;
  4674.     else
  4675.       return FLOAT(INTEGER(X + HALF));
  4676.     end if;
  4677.   end TRUNCATE;
  4678.  
  4679.   function ROUND(X : FLOAT) return FLOAT is
  4680.   begin
  4681.     return FLOAT(INTEGER(X));
  4682.   end ROUND;
  4683.  
  4684.  
  4685.   package KEY is
  4686.     X : INTEGER := 10_001;
  4687.     Y : INTEGER := 20_001;
  4688.     Z : INTEGER := 30_001;
  4689.   end KEY;
  4690.  
  4691.   function RAN return FLOAT is
  4692.   --  This rectangular random number routine is adapted from a report
  4693.   --  "A Pseudo-Random Number Generator" by B. A. Wichmann and I. D. Hill
  4694.   --  NPL Report DNACS XX (to be published)
  4695.   --  In this stripped version, it is suitable for machines supporting 
  4696.   --  INTEGER at only 16 bits and is portable in Ada
  4697.     W : FLOAT;
  4698.   begin
  4699.  
  4700.     KEY.X := 171 * (KEY.X mod 177 - 177) -  2 * (KEY.X / 177);
  4701.     if KEY.X < 0  then
  4702.       KEY.X := KEY.X + 30269;
  4703.     end if;
  4704.  
  4705.     KEY.Y := 172 * (KEY.Y mod 176 - 176) - 35 * (KEY.Y / 176);
  4706.     if KEY.Y < 0  then
  4707.       KEY.Y := KEY.Y + 30307;
  4708.     end if;
  4709.  
  4710.     KEY.Z := 170 * (KEY.Z mod 178 - 178) - 63 * (KEY.Z / 178);
  4711.     if KEY.Z < 0  then
  4712.       KEY.Z := KEY.Z + 30323;
  4713.     end if;
  4714.  
  4715.     --  CONVERT_TO_FLOAT is used instead of FLOAT since the floating
  4716.     --  type may be software defined
  4717.  
  4718.     W :=     CONVERT_TO_FLOAT(KEY.X)/30269.0
  4719.            + CONVERT_TO_FLOAT(KEY.Y)/30307.0
  4720.            + CONVERT_TO_FLOAT(KEY.Z)/30323.0;
  4721.  
  4722.     return  W - CONVERT_TO_FLOAT(INTEGER(W - 0.5));
  4723.  
  4724.   end RAN;
  4725.  
  4726. begin
  4727.   PI            := CONVERT_TO_FLOAT(INTEGER(3)) +
  4728.                    CONVERT_TO_FLOAT(MANTISSA_TYPE(0.14159_26535_89793_23846));
  4729.   ONE_OVER_PI   := CONVERT_TO_FLOAT(MANTISSA_TYPE(0.31830_98861_83790_67154));
  4730.   TWO_OVER_PI   := CONVERT_TO_FLOAT(MANTISSA_TYPE(0.63661_97723_67581_34308));
  4731.   PI_OVER_TWO   := CONVERT_TO_FLOAT(INTEGER(1)) +
  4732.                    CONVERT_TO_FLOAT(MANTISSA_TYPE(0.57079_63267_94896_61923));
  4733.   PI_OVER_THREE := CONVERT_TO_FLOAT(INTEGER(1)) +
  4734.                    CONVERT_TO_FLOAT(MANTISSA_TYPE(0.04719_75511_96597_74615));
  4735.   PI_OVER_FOUR  := CONVERT_TO_FLOAT(MANTISSA_TYPE(0.78539_81633_97448_30962));
  4736.   PI_OVER_SIX   := CONVERT_TO_FLOAT(MANTISSA_TYPE(0.52359_87755_98298_87308));
  4737.  
  4738. end NUMERIC_PRIMITIVES;
  4739. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4740. --worldmap.txt
  4741. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4742. with Graphic, Core_Functions, Trig_Lib, Numeric_Primitives,
  4743.      World_Menus, Menu_Draw, World_Data_Files;
  4744. use  Graphic, Core_Functions, Trig_Lib, Numeric_Primitives,
  4745.      World_Menus, Menu_types;
  4746. package body World_Map is
  4747.  
  4748. procedure Draw_Map is
  4749. -- Draw the map defined by the World_Menus package.
  4750. type Beam_Or_Symbol is (Map_Data, Beam_Data, Symbol_Data);
  4751.   Eps     : constant float := 1.0E-7;  -- Small number used to avoid divide by zero errors.
  4752.   Way_Out : constant float := 1.0E+8;  -- A location always off the screen.
  4753.   Radians_Per_Degree : constant float := 0.0174532925;
  4754.   Degrees_Per_Radian : constant float := 57.295779510;
  4755.   Max_Points  : constant := 400;
  4756.   type Float_Array is array (1..Max_Points) of float;
  4757.   Map_Color   : constant Color_Selection 
  4758.                            := World_Menus.Current_Color_Selection;
  4759.   Limit_Type  : constant Kind_Of_Projection_Limit
  4760.                            := Type_Of_Projection_Limit;
  4761.   Projection  : Kind_Of_Projection := Type_Of_Projection;
  4762.   Proj_Params : Projection_Parameters;
  4763.   Specials    : constant Special_Displays := Current_Special_Displays;
  4764.   Max_Line    : float;  -- The longest allowable line on the screen.
  4765.   Phio        : float;  -- The longitude center of the projection.
  4766.   Symbol      : integer;-- The symbol to be used  1 --> Square
  4767.                         --                        2 --> Plus
  4768.                         --                        3 --> Diamond
  4769.                         --                        4 --> Triangle
  4770.   Symbol_Size : float;  -- The size of the symbol to be drawn is
  4771.   Symbol_Scale: constant float := 100.0; -- <window width> / Symbol_Scale.
  4772.   Lon_Pic_Min,
  4773.   Lon_Pic_Max,          -- The min's and max's of the viewport
  4774.   Lat_Pic_Min,          -- used to avoid plotting points that cannot
  4775.   Lat_Pic_Max : float;  -- possibly be visible.
  4776.   SinO,
  4777.   CosO,                 -- Sin and Cos of the center of the projection
  4778.   SinR,
  4779.   CosR : float;         -- Sin and Cos of the rotation
  4780.   Umin,
  4781.   Umax,                 -- The basis for determining the windowing
  4782.   Vmin,                 -- of the Viewport.
  4783.   Vmax : float;
  4784.   Caught_Error : exception;
  4785.  
  4786.   function Sat_Scale(Alt, Ref_Alt : float) return float is
  4787.   -- Finds scale for satellite view.
  4788.     Earth_Radius : constant float := 3443.9336;
  4789.     F, H, Alfa, Beta : float;
  4790.   begin
  4791.     if Alt <= 0.0 then
  4792.       Menu_Draw.Draw_Error_Port("Invalid Satellite Altitude.",
  4793.                                 "Plot aborted.");
  4794.       raise Caught_Error;
  4795.     elsif Ref_Alt <= 0.0 then
  4796.       Menu_Draw.Draw_Error_Port("Invalid Satellite Reference Altitude.",
  4797.                                 "Plot aborted.");
  4798.       raise Caught_Error;
  4799.     end if;
  4800.     F    := Ref_Alt / Earth_Radius;
  4801.     H    := Alt     / Earth_Radius;
  4802.     Beta := ASin(1.0 / (1.0 + H));
  4803.     Alfa := ASin(1.0 / (1.0 + F));
  4804.     F    := Tan(Beta) / Tan(Alfa);
  4805.     return F / (H * Beta);
  4806.   end Sat_Scale;
  4807.  
  4808.   procedure Project(Lat, Lon : in float; U, V : out float) is
  4809.   -- Sets up the calls to the various projection algorithms.
  4810.   -- The point (Lat, Lon) is input in degrees and is transformed
  4811.   -- to (U, V) in the mapping coordinates according to the kind
  4812.   -- of projection.
  4813.     R, H, SinA, CosA, SinB, CosB, SinPH, CosPH, SinLat, CosLat : float;
  4814.     Del_Lon : float;
  4815.  
  4816.     function Calc_Del_Lon(Lon : float) return float is
  4817.     -- Offsets Lon by the center of the projection adjusting for wraparound.
  4818.       Del_Lon : float;
  4819.     begin
  4820.       Del_Lon := Lon - Phio;
  4821.       if Del_Lon >= 180.0 then
  4822.         Del_Lon := Del_Lon - 360.0;
  4823.       elsif Del_Lon < -180.0 then
  4824.         Del_Lon := Del_Lon + 360.0;
  4825.       end if;
  4826.       return Del_Lon;
  4827.     end Calc_Del_Lon;
  4828.  
  4829.     procedure Do_Trig_Calculations is
  4830.     begin
  4831.       SinPH  := Sin(Del_Lon * Radians_Per_Degree);
  4832.       CosPH  := Cos(Del_Lon * Radians_Per_Degree);
  4833.       SinLat := Sin(    Lat * Radians_Per_Degree);
  4834.       CosLat := Cos(    Lat * Radians_Per_Degree);
  4835.       CosA   := SinLat*SinO + CosLat*CosO*CosPH;
  4836.       if abs(CosA) > 1.0 then
  4837.         CosA := Sign(1.0, CosA);
  4838.       end if;
  4839.       SinA := Sqrt( 1.0 + Eps - CosA*CosA);
  4840.       SinB := CosLat * SinPH / SinA;
  4841.       CosB := (SinLat*CosO - CosLat*SinO*CosPH) / SinA;
  4842.     end Do_Trig_Calculations;
  4843.  
  4844.    procedure Cylin(Lat, Lon : in float; U, V : out float) is
  4845.     -- This is a cylindrcal projection routine.
  4846.     -- Point (Lat, Lon) is transformed to mapping coordinates (U, V).
  4847.       Out_Of_Range : exception;
  4848.     begin
  4849.       Del_Lon := Calc_Del_Lon(Lon);
  4850.       if Proj_Params.Lat_Center = 0.0 then
  4851.         Case Projection is
  4852.           when Cartesian => U := Del_Lon;
  4853.                             V := Lat;
  4854.           when Mercator  => U := Del_Lon * Radians_Per_Degree;
  4855.                             V := Log( Tan(0.00872664*(Lat+90.0001)) );
  4856.           when others    => null;
  4857.         end case;
  4858.       else
  4859.         Do_Trig_Calculations;
  4860.         Case Projection is
  4861.           when Cartesian =>
  4862.             if abs(1.0 - CosA*CosA) < 1.0E-4 then
  4863.               raise Out_Of_Range;
  4864.             end if;
  4865.             U := ATan2(SinB*CosR + CosB*SinR, SinB*SinR - CosB*CosR)
  4866.                  * Degrees_Per_Radian;
  4867.             V := 90.0 - ACos(CosA)*Degrees_Per_Radian;
  4868.           when Mercator  =>
  4869.             if abs(1.0 - CosA*CosA) < 2.0E-6 then
  4870.               raise Out_Of_Range;
  4871.             end if;
  4872.             U := ATan2(SinB*CosR + CosB*SinR, SinB*SinR - CosB*CosR);
  4873.             V := Log( (1.0+CosA) / SinA);
  4874.           when others    => null;
  4875.         end case;
  4876.       end if;
  4877.     exception
  4878.       when Out_Of_Range =>
  4879.         U := Way_Out;
  4880.         V := Way_Out;
  4881.     end Cylin;
  4882.  
  4883.     procedure Azim(Lat, Lon : in float; U, V : out float) is
  4884.     -- This is an Azimuthal projection routine.
  4885.     -- Point (Lat, Lon) is transformed to mapping coordinates (U, V).
  4886.       R, H : float;
  4887.       Out_Of_Range : exception;
  4888.     begin  -- Azim
  4889.       Del_Lon := Calc_Del_Lon(Lon);
  4890.       Do_Trig_Calculations;
  4891.       case Projection is
  4892.         when Stereographic =>
  4893.           R := (1.0 - CosA) / SinA;
  4894.         when Gnomonic     => null;
  4895.           if CosA <= 0.0 then
  4896.             raise Out_Of_Range;
  4897.           end if;
  4898.           R := SinA / CosA;
  4899.         when Lambert      =>
  4900.           if abs(CosA+1.0) < 1.0E-6 then
  4901.             raise Out_Of_Range;
  4902.           end if;
  4903.           R := (1.0 + CosA) / SinA;
  4904.           R := 2.0 / (Sqrt(1.0 + R*R));
  4905.         when Orthographic =>
  4906.           if CosA <= 0.0 then
  4907.             raise Out_Of_Range;
  4908.           end if;
  4909.           R := SinA;
  4910.         when Satellite    =>
  4911.           H := Proj_Params.Sat_Altitude / 3444.0;
  4912.           if (CosA - 1.0/(H+1.0)) <= 0.0 then
  4913.             raise Out_Of_Range;
  4914.           end if;
  4915.           R := Sat_Scale(Proj_Params.Sat_Altitude, Proj_Params.View_Altitude)
  4916.                  * H * ATan( SinA / (H+1.0-CosA));
  4917.         when Azimuthal    => null;
  4918.           if abs(CosA+1.0) < 1.0E-6 then
  4919.             raise Out_Of_Range;
  4920.           end if;
  4921.           R := ACos(CosA);
  4922.         when others       => null;
  4923.       end case;
  4924.       U := R * (SinB*CosR + CosB*SinR);
  4925.       V := R * (CosB*CosR - SinB*SinR);
  4926.     exception
  4927.       when Out_Of_Range =>
  4928.         U := Way_Out;
  4929.         V := Way_Out;
  4930.     end Azim;
  4931.  
  4932.   begin  -- Project
  4933.     case Projection is
  4934.       when Cartesian  |
  4935.            Mercator   => Cylin(Lat, Lon, U, V);
  4936.       when others     => Azim(Lat, Lon, U, V);
  4937.     end case;
  4938.   end Project;
  4939.  
  4940.   procedure Initialize_Plot is
  4941.   -- Sets Umin, Umax, Vmin, and Vmax.  In other words, it determines
  4942.   -- the minimums and maximums of the viewing of the projection.
  4943.   -- These four variables are what determine the "zooming" characteristics.
  4944.     Limits : constant Projection_Limits
  4945.                := World_Menus.Current_Projection_Limits;
  4946.     Phia   : float;      -- the latitude center of the projection.
  4947.     SinO1, CosO1 : float;
  4948.  
  4949.     procedure Do_All_Earth is
  4950.     -- Set limits to see as much of the earth is possible for this projection.
  4951.     begin
  4952.       case Projection is
  4953.         when Stereographic |
  4954.              Gnomonic     |
  4955.              Lambert      => Umin := -2.0;
  4956.                              Umax :=  2.0;
  4957.                              Vmin := -2.0;
  4958.                              Vmax :=  2.0;
  4959.         when Orthographic |
  4960.              Satellite    => Umin := -1.0;
  4961.                              Umax :=  1.0;
  4962.                              Vmin := -1.0;
  4963.                              Vmax :=  1.0;
  4964.         when Azimuthal    |
  4965.              Mercator     => Umin := -180.0 * Radians_Per_Degree;
  4966.                              Umax := -Umin;
  4967.                              Vmin :=  Umin * 0.9;
  4968.                              Vmax :=  Umax;
  4969.         when Cartesian    => Umin := -180.0;
  4970.                              Umax :=  180.0;
  4971.                              Vmin :=  -90.0;
  4972.                              Vmax :=   90.0;
  4973.       end case;
  4974.     end Do_All_Earth;
  4975.  
  4976.     procedure Force_In_Bounds(Umin, Umax, Vmin, Vmax : in out float) is
  4977.     -- Given a projection such as orthographic, not all of the points can
  4978.     -- can be plotted for a given projection because they will be on the
  4979.     -- other side of the globe.  The user may zoom in by giving limits
  4980.     -- where some of them are on the other side of the globe.
  4981.     --   This routine adjusts to limits which are not visible by adjusting
  4982.     -- the limit to be on the horizon or the line between visibility and
  4983.     -- invisibility.
  4984.     begin
  4985.       if Umin >= Way_Out then
  4986.         case Projection is
  4987.           when Stereographic |
  4988.                Gnomonic      |
  4989.                Lambert      => Umin :=   -2.0;
  4990.           when Orthographic |
  4991.                Satellite    => Umin :=   -1.0;
  4992.           when Azimuthal    |
  4993.                Mercator     => Umin := -180.0 * Radians_Per_Degree;
  4994.           when Cartesian    => Umin := -180.0;
  4995.         end case;
  4996.       end if;
  4997.       if Umax >= Way_Out then
  4998.         case Projection is
  4999.           when Stereographic |
  5000.                Gnomonic      |
  5001.                Lambert      => Umax :=   2.0;
  5002.           when Orthographic |
  5003.                Satellite    => Umax :=   1.0;
  5004.           when Azimuthal    |
  5005.                Mercator     => Umax := 180.0 * Radians_Per_Degree;
  5006.           when Cartesian    => Umax := 180.0;
  5007.         end case;
  5008.       end if;
  5009.       if Vmin >= Way_Out then
  5010.         case Projection is
  5011.           when Stereographic |
  5012.                Gnomonic      |
  5013.                Lambert      => Vmin :=   -2.0;
  5014.           when Orthographic |
  5015.                Satellite    => Vmin :=   -1.0;
  5016.           when Azimuthal    |
  5017.                Mercator     => Vmin := -180.0 * Radians_Per_Degree;
  5018.           when Cartesian    => Vmin :=  -90.0;
  5019.         end case;
  5020.       end if;
  5021.       if Vmax >= Way_Out then
  5022.         case Projection is
  5023.           when Stereographic |
  5024.                Gnomonic      |
  5025.                Lambert      => Vmax :=   2.0;
  5026.           when Orthographic |
  5027.                Satellite    => Vmax :=   1.0;
  5028.           when Azimuthal    |
  5029.                Mercator     => Vmax := 180.0 * Radians_Per_Degree;
  5030.           when Cartesian    => Vmax :=  90.0;
  5031.         end case;
  5032.       end if;
  5033.     end Force_In_Bounds;
  5034.  
  5035.     procedure Do_Min_Max_Lat_Lon is
  5036.     -- Limits are defined by min/max latitudes and min/max longitudes.
  5037.       U1, V1, U2, V2 : float;
  5038.  
  5039.       function Max(X, Y : float) return float is
  5040.       begin
  5041.         if X > Y then
  5042.           return X;
  5043.         else
  5044.           return Y;
  5045.         end if;
  5046.       end Max;
  5047.  
  5048.       function Min(X, Y : float) return float is
  5049.       begin
  5050.         if X > Y then
  5051.           return Y;
  5052.         else
  5053.           return X;
  5054.         end if;
  5055.       end Min;
  5056.  
  5057.     begin  -- Do_Min_Max_Lat_Lon
  5058.       Lat_Pic_Min := Limits.Min_Lat_Lon.Y;
  5059.       Lat_Pic_Max := Limits.Max_Lat_Lon.Y;
  5060.       Lon_Pic_Min := Limits.Min_Lat_Lon.X;
  5061.       Lon_Pic_Max := Limits.Max_Lat_Lon.X;
  5062.       Project(Lat_Pic_Min, Lon_Pic_Min, U1, V1);
  5063.       Project(Lat_Pic_Max, Lon_Pic_Min, U2, V2);
  5064.       Force_In_Bounds(U1, V1, U2, V2);
  5065.       Vmin := Min(V1, V2);
  5066.       Vmax := Max(V1, V2);
  5067.       Umin := Min(U1, U2);
  5068.       Umax := Max(U1, U2);
  5069.     end Do_Min_Max_Lat_Lon;
  5070.  
  5071.     procedure Do_Min_Max_Coordinates is
  5072.     -- Limits are defined by two points of a rectangle, one in the upper
  5073.     -- right corner and one in the lower left corner.
  5074.       TUmin, TVmin, TUmax, TVmax : float;
  5075.  
  5076.       function Map(Val, Max_Val : float) return float is
  5077.       begin
  5078.         if Val > Max_Val then
  5079.           return Val - 2.0*Max_Val;
  5080.         else
  5081.           return Val;
  5082.         end if;
  5083.       end Map;
  5084.  
  5085.     begin  -- Do_Min_Max_Coordinates
  5086.       Lon_Pic_Min := Map(Limits.South_West.X, 180.0);
  5087.       Lon_Pic_Max := Map(Limits.North_East.X, 180.0);
  5088.       Lat_Pic_Min := Map(Limits.South_West.Y,  90.0);
  5089.       Lat_Pic_Max := Map(Limits.North_East.Y,  90.0);
  5090.       Project(Lat_Pic_Min, Lon_Pic_Min, TUmin, TVmin);
  5091.       Project(Lat_Pic_Max, Lon_Pic_Max, TUmax, TVmax);
  5092.       Force_In_Bounds(TUmin, TUmax, TVmin, TVmax);
  5093.       Umin := TUmin;
  5094.       Vmin := TVmin;
  5095.       Umax := TUmax;
  5096.       Vmax := TVmax;
  5097.     end Do_Min_Max_Coordinates;
  5098.  
  5099.     procedure Do_Angular is
  5100.     -- Limits are determined by earth central angles.
  5101.       TUmin   : float := Limits.Angle_Left;
  5102.       TUmax   : float := Limits.Angle_Right;
  5103.       TVmin   : float := Limits.Angle_Down;
  5104.       TVmax   : float := Limits.Angle_Up;
  5105.       CosUmin : constant float := Cos(TUmin * Radians_Per_Degree);
  5106.       SinUmin : constant float := Sqrt(1.0 + Eps - CosUmin*CosUmin);
  5107.       CosUmax : constant float := Cos(TUmax * Radians_Per_Degree);
  5108.       SinUmax : constant float := Sqrt(1.0 + Eps - CosUmax*CosUmax);
  5109.       CosVmin : constant float := Cos(TVmin * Radians_Per_Degree);
  5110.       SinVmin : constant float := Sqrt(1.0 + Eps - CosVmin*CosVmin);
  5111.       CosVmax : constant float := Cos(TVmax * Radians_Per_Degree);
  5112.       SinVmax : constant float := Sqrt(1.0 + Eps - CosVmax*CosVmax);
  5113.       Bad_Limits : exception;
  5114.     begin
  5115.       case Projection is
  5116.         when Stereographic =>
  5117.                Umin := -(1.0 - CosUmin) / SinUmin;
  5118.                Umax :=  (1.0 - CosUmax) / SinUmax;
  5119.                Vmin := -(1.0 - CosVmin) / SinVmin;
  5120.                Umax :=  (1.0 - CosUmax) / SinUmax;
  5121.         when Orthographic  =>
  5122.                if TUmin > 90.0 or
  5123.                   TUmax > 90.0 or
  5124.                   TVmin > 90.0 or
  5125.                   TUmax > 90.0 then
  5126.                  raise Bad_Limits;
  5127.                end if;
  5128.                Umin := -SinUmin;
  5129.                Umax :=  SinUmax;
  5130.                Vmin := -SinVmin;
  5131.                Vmax :=  SinVmax;
  5132.         when Gnomonic     =>
  5133.                if TUmin >= 90.0 or
  5134.                   TUmax >= 90.0 or
  5135.                   TVmin >= 90.0 or
  5136.                   TUmax >= 90.0 then
  5137.                  raise Bad_Limits;
  5138.                end if;
  5139.                Umin := -SinUmin / CosUmin;
  5140.                Umax :=  SinUmax / CosUmax;
  5141.                Vmin := -SinVmin / CosVmin;
  5142.                Vmax :=  SinVmax / CosVmax;
  5143.         when Lambert      =>
  5144.                TUmin := (1.0 + CosUmin) / SinUmin;
  5145.                Umin  := -2.0 / Sqrt(1.0 + TUmin*TUmin);
  5146.                TUmax := (1.0 + CosUmax) / SinUmax;
  5147.                Umax  :=  2.0 / Sqrt(1.0 + TUmax*TUmax);
  5148.                TVmin := (1.0 + CosVmin) / SinVmin;
  5149.                Vmin  := -2.0 / Sqrt(1.0 + TVmin*TVmin);
  5150.                TVmax := (1.0 + CosVmax) / SinVmax;
  5151.                Vmax  :=  2.0 / Sqrt(1.0 + TVmax*TVmax);
  5152.         when Azimuthal    =>
  5153.                Umin := -TUmin * Radians_Per_Degree;
  5154.                Umax :=  TUmax * Radians_Per_Degree;
  5155.                Vmin := -TVmin * Radians_Per_Degree;
  5156.                Vmax :=  TVmax * Radians_Per_Degree;
  5157.         when Cartesian    =>
  5158.                Umin := -TUmin;
  5159.                Umax :=  TUmax;
  5160.                Vmin := -TVmin;
  5161.                Vmax :=  TVmax;
  5162.         when Mercator     =>
  5163.                if TVmin >= 90.0 or
  5164.                   TUmax >= 90.0 then
  5165.                  raise Bad_Limits;
  5166.                end if;
  5167.                Umin := -TUmin * Radians_Per_Degree;
  5168.                Umax :=  TUmax * Radians_Per_Degree;
  5169.                Vmin := -Log((1.0+SinVmin) / CosVmin);
  5170.                Vmax :=  Log((1.0+SinVmax) / CosVmax);
  5171.         when Satellite    =>
  5172.                Umin := -1.0;
  5173.                Umax :=  1.0;
  5174.                Vmin := -1.0;
  5175.                Vmax :=  1.0;
  5176.       end case;
  5177.     exception
  5178.       when Bad_Limits =>
  5179.         Menu_Draw.Draw_Error_Port("Angular limits too great.",
  5180.                                   "Plot aborted.");
  5181.         raise Caught_Error;
  5182.     end Do_Angular;
  5183.  
  5184.     procedure Do_Lat_Lon_Boundary is
  5185.     -- Limits are determined by four points, one on each of the four
  5186.     -- sides of a rectangle.
  5187.       U1, V1, U2, V2, U3, V3, U4, V4 : float;
  5188.     begin
  5189.       Lat_Pic_Min := Limits.Point_Down.Y;
  5190.       Lat_Pic_Max := Limits.Point_Up.Y;
  5191.       Lon_Pic_Min := Limits.Point_Left.X;
  5192.       Lon_Pic_Max := Limits.Point_Right.X;
  5193.       Project(Limits.Point_Left.Y,  Lon_Pic_Min,         U1, V1);
  5194.       Project(Lat_Pic_Min,          Limits.Point_Down.X, U2, V2);
  5195.       Project(Limits.Point_Right.Y, Lon_Pic_Max,         U3, V3);
  5196.       Project(Lat_Pic_Max,          Limits.Point_Up.X,   U4, V4);
  5197.       Force_In_Bounds(U1, U3, V2, V4);
  5198.       Umin := U1;
  5199.       Umax := U3;
  5200.       Vmin := V2;
  5201.       Vmax := V4;
  5202.     end Do_Lat_Lon_Boundary;
  5203.  
  5204.     procedure Do_Off_Center_Latitude is
  5205.     -- Set up for projections with centers off Latitude 0.0.
  5206.     begin
  5207.       case Projection is
  5208.         when Cartesian | Mercator =>
  5209.           if Phia = 0.0 and Proj_Params.Clk_Rot_Ar_Cent = 0.0 then
  5210.             SinO :=  1.0;
  5211.             CosO :=  0.0;
  5212.             SinR :=  0.0;
  5213.             CosR :=  1.0;
  5214.           elsif Phia = 0.0 and abs(Proj_Params.Clk_Rot_Ar_Cent) = 180.0 then
  5215.             Phio := Phio + 180.0;
  5216.             SinO := -1.0;
  5217.             CosO :=  0.0;
  5218.             SinR :=  0.0;
  5219.             CosR :=  1.0;
  5220.           else
  5221.             SinO1 := CosO*CosR;
  5222.             CosO1 := Sqrt(1.0 + Eps - SinO1*SinO1);
  5223.             Phio  := Phio - ATan2(SinR/CosO1, -CosR*SinO/CosO1)
  5224.                        * Degrees_Per_Radian;
  5225.             SinR  := SinR * CosO/CosO1;
  5226.             CosR  := -SinO/CosO1;
  5227.             SinO  := SinO1;
  5228.             CosO  := CosO1;
  5229.           end if;
  5230.         when others     => null;
  5231.       end case;
  5232.     end Do_Off_Center_Latitude;
  5233.  
  5234.     procedure Set_Scaling is
  5235.     -- Sets the windowing of the viewport.
  5236.     -- Also determines the maximum line to be drawn to avoid wraparound problems.
  5237.     -- Also determines the size of the symbols to be drawn.
  5238.       X_Max : constant float := 17.0; -- Maximum these can ever be under
  5239.       Y_Max : constant float := 11.0; --   any circumstances.
  5240.       Scale : constant Plot_Characteristics := World_Menus.Current_Plot_Char;
  5241.       Delta_U, Delta_V : float;
  5242.       Left, Bottom, Right, Top: float;
  5243.     begin
  5244.       Delta_U := abs(Umax - Umin);
  5245.       Delta_V := abs(Vmax - Vmin);
  5246.       if Delta_U*0.6 > Delta_V then
  5247.         Left   := Umin;
  5248.         Right  := Umax;
  5249.         Top    := (Vmin + Vmax) / 2.0;
  5250.         Bottom := Top;
  5251.         Symbol_Size := (Right - Left) * 0.6 / Symbol_Scale;
  5252.       else
  5253.         Top    := Vmax;
  5254.         Bottom := Vmin;
  5255.         Left   := (Umin + Umax) / 2.0;
  5256.         Right  := Left;
  5257.         Symbol_Size := (Top - Bottom) / Symbol_Scale;
  5258.       end if;
  5259.     -- Set View_Port here 
  5260.       Set_Window(Left, Bottom, Right, Top);
  5261.     -- calculate the length of a 30 degree line at the center of the projection
  5262.       Project(0.0, Proj_Params.Lon_Center-15.0, Left,  Top);
  5263.       Project(0.0, Proj_Params.Lon_Center+15.0, Right, Top);
  5264.     -- Make that the maximum length line drawable
  5265.       Max_Line := abs(Right - Left);
  5266.     end Set_Scaling;
  5267.  
  5268.   begin  -- Initialize_Plot
  5269.     Lat_Pic_Max :=   90.0;
  5270.     Lat_Pic_Min :=  -90.0;
  5271.     Lon_Pic_Max :=  180.0;
  5272.     Lon_Pic_Min := -180.0;
  5273.     Phia := Proj_Params.Lat_Center;
  5274.     Phio := Proj_Params.Lon_Center;
  5275.     SinR := Sin(Proj_Params.Clk_Rot_Ar_Cent * Radians_Per_Degree);
  5276.     CosR := Cos(Proj_Params.Clk_Rot_Ar_Cent * Radians_Per_Degree);
  5277.     SinO := Sin(Phia * Radians_Per_Degree);
  5278.     CosO := Cos(Phia * Radians_Per_Degree);
  5279.     Do_Off_Center_Latitude;
  5280.     case Type_Of_Projection_Limit is
  5281.       when All_Earth =>
  5282.         Do_All_Earth;
  5283.       when Min_Max_Lat_Lon =>
  5284.         Do_Min_Max_Lat_Lon;
  5285.       when Min_Max_Coordinates =>
  5286.         Do_Min_Max_Coordinates;
  5287.       when Angular_Dist_From_Projection_Center =>
  5288.         Do_Angular;
  5289.       when Lat_Lon_Boundary =>
  5290.         Do_Lat_Lon_Boundary;
  5291.     end case;      
  5292.     Set_Scaling;
  5293.   end Initialize_Plot;
  5294.  
  5295.   procedure Graff(NPts : in integer; U, V : in Float_Array;
  5296.                   Mode : in integer) is
  5297.   -- Plots arrays NPts points from U and V.
  5298.   -- Mode : 1 - Line plot
  5299.   --        2 - Point plot
  5300.   --        3 - connect every other point (for grids)
  5301.     Line_Mode  : constant := 1;
  5302.     Point_Mode : constant := 2;
  5303.     Dash_Mode  : constant := 3;
  5304.     Even       : boolean  := true;
  5305.  
  5306.     procedure Square(Center_X, Center_Y, Size : in float) is
  5307.       Half_Size : constant float := Size / 2.0;
  5308.     begin
  5309.       Move_To(Center_X + Half_Size, Center_Y + Half_Size);
  5310.       Line( Size, 0.0);
  5311.       Line(0.0, -Size);
  5312.       Line(-Size, 0.0);
  5313.       Line(0.0,  Size);
  5314.     end Square;
  5315.  
  5316.     procedure Plus(Center_X, Center_Y, Size : in float) is
  5317.       Half_Size : constant float := Size / 2.0;
  5318.     begin
  5319.       Move_To(Center_X - Half_Size, Center_Y);
  5320.       Line(Size, 0.0);
  5321.       Move_To(Center_X, Center_Y - Half_Size);
  5322.       Line(0.0, Size);
  5323.     end Plus;
  5324.  
  5325.     procedure Diamond(Center_X, Center_Y, Size : in float) is
  5326.       Half_Size : constant float := Size / 2.0;
  5327.       Horisize  : constant float := Half_Size * 0.75;
  5328.     begin
  5329.       Move_To(Center_X, Center_Y + Half_Size);
  5330.       Line( Horisize, -Half_Size);
  5331.       Line(-Horisize, -Half_Size);
  5332.       Line(-Horisize,  Half_Size);
  5333.       Line( Horisize,  Half_Size);
  5334.     end Diamond;
  5335.  
  5336.     procedure Triangle(Center_X, Center_Y, Size : in float) is
  5337.       Half_Size : constant float := Size / 2.0;
  5338.       Bottom    : constant float := Size * 0.433;
  5339.     begin
  5340.       Move_To(Center_X - Half_Size, Center_Y - Bottom);
  5341.       Line(Size, 0.0);
  5342.       Line(-Half_Size,  Size);
  5343.       Line(-Half_Size, -Size);
  5344.     end Triangle;
  5345.  
  5346.   begin  -- Graff
  5347.     Move_To(U(1), V(1));
  5348.     case Mode is
  5349.       when Line_Mode  => 
  5350.         for I in 2..NPts loop
  5351.           if abs(U(I) - U(I-1)) > Max_Line THEN
  5352.             Move_To(U(I), V(I));
  5353.           else
  5354.             Line_To(U(I), V(I));
  5355.           end if;
  5356.         end loop;
  5357.       when Point_Mode =>
  5358.         for I in 1 .. NPts loop
  5359.           case Symbol is
  5360.             when 1      => Square  (U(I), V(I), Symbol_Size);
  5361.             when 2      => Plus    (U(I), V(I), Symbol_Size);
  5362.             when 3      => Diamond (U(I), V(I), Symbol_Size);
  5363.             when others => Triangle(U(I), V(I), Symbol_Size);
  5364.           end case;
  5365.         end loop;
  5366.       when Dash_Mode  =>
  5367.         for I in 2..NPts loop
  5368.           if Even then
  5369.             if U(I-1) /= Way_Out then
  5370.               if abs(U(I) - U(I-1)) > Max_Line THEN
  5371.                 Move_To(U(I), V(I));
  5372.               else
  5373.                 Line_To(U(I), V(I));
  5374.               end if;
  5375.             end if;
  5376.           else
  5377.             Move_To(U(I), V(I));
  5378.           end if;
  5379.           Even := not Even;
  5380.         end loop;
  5381.       when others => null;
  5382.     end case;
  5383.   end Graff;
  5384.  
  5385.   procedure Plot_Points(Points_Type : Beam_Or_Symbol; Name_Length : integer;
  5386.                         File_Name : FileName; Draw_Color : Color_Type) is
  5387.   -- Plots map, beam, and symbol data.
  5388.   use World_Data_Files;
  5389.     Lat_Lon : Lat_Lon_Record;
  5390.     Point_File : World_Data_Io.File_Type;
  5391.  
  5392.     procedure Plot_Rec(Rec : Lat_Lon_Record) is
  5393.       Stop : constant integer := 2 * Lat_Lon.Number_Of_Pairs;
  5394.       N, I, NPts : integer;
  5395.       Draw_Mode  : integer;
  5396.       ProjU, ProjV : Float_Array;
  5397.     begin
  5398.       if Points_Type = Symbol_Data then
  5399.         Draw_Mode := 2;
  5400.       else
  5401.         Draw_Mode := 1;
  5402.       end if;
  5403.       NPts := 0;
  5404.       I    := 1;
  5405.       loop
  5406.         exit when I > Stop;
  5407.         NPts := NPts + 1;
  5408.         Project(Lat_Lon.Lat_Lon_Pairs(I), Lat_Lon.Lat_Lon_Pairs(I+1),
  5409.                 ProjU(NPts), ProjV(NPts));
  5410.         if NPts = Max_Points then
  5411.           Graff(Max_Points, ProjU, ProjV, Draw_Mode);
  5412.           ProjU(1) := ProjU(Max_Points);
  5413.           ProjV(1) := ProjV(Max_Points);
  5414.           NPts     := 1;
  5415.         end if;
  5416.         I := I + 2;
  5417.       end loop;
  5418.       if NPts > 1 then
  5419.         Graff(NPts, ProjU, ProjV, Draw_Mode);
  5420.       end if;
  5421.     end Plot_Rec;
  5422.  
  5423.     function In_View return boolean is
  5424.     -- Determines whether or not the current record will be visible
  5425.     -- in the window.
  5426.       Lat_Min : constant float := Lat_Lon.Minimum_Lat;
  5427.       Lat_Max : constant float := Lat_Lon.Maximum_Lat;
  5428.       Lon_Min :          float := Lat_Lon.Minimum_Lon;
  5429.       Lon_Max :          float := Lat_Lon.Maximum_Lon;
  5430.     begin
  5431.       if Lon_Max > 180.0 then
  5432.         Lon_Min := Lon_Min - 180.0;
  5433.         Lon_Max := Lon_Max - 180.0;
  5434.       end if;
  5435.       if Lat_Min >= Lat_Pic_Max or else
  5436.          Lon_Min >= Lon_Pic_Max or else
  5437.          Lat_Max <= Lat_Pic_Min or else
  5438.          Lon_Max <= Lon_Pic_Min then
  5439.         return false;
  5440.       else
  5441.         return true;
  5442.       end if;
  5443.     end In_View;
  5444.  
  5445.   begin  -- Plot_Points
  5446.     World_Data_Io.Open(Point_File, World_Data_Io.in_file,
  5447.                        File_Name(1..Name_Length), "");
  5448.     Set_Mode(Graphics);
  5449.     Set_Color(Draw_Color);
  5450.     while not World_Data_Io.end_of_file(Point_File) loop
  5451.       World_Data_Io.Read(Point_File, Lat_Lon);
  5452.       if Points_Type = Symbol_Data  then
  5453.         Symbol := integer(Lat_Lon.Minimum_Lat);
  5454.         Plot_Rec(Lat_Lon);
  5455.       elsif In_View then
  5456.         Plot_Rec(Lat_Lon);
  5457.       end if;
  5458.     end loop;
  5459.     Set_Mode(Text);
  5460.   exception
  5461.     when World_Data_Io.Name_Error =>
  5462.       if Points_Type = Map_Data then
  5463.         Menu_Draw.Draw_Error_Port("Map file not found.", "");
  5464.       elsif Points_Type = Beam_Data then
  5465.         Menu_Draw.Draw_Error_Port("Beam file not found.", "");
  5466.       else
  5467.         Menu_Draw.Draw_Error_Port("Symbol file not found.", "");
  5468.       end if;
  5469.   end Plot_Points;
  5470.  
  5471.   procedure Draw_Limb is
  5472.   -- Draws Limb line around map.
  5473.     Segments : constant integer := 73; -- 5 degree increments (360/5 + 1)
  5474.     Sin1 : constant float := 8.71557420E-2; -- sin(360/(Segments-1))
  5475.     Cos1 : constant float := 9.96194698E-1; -- cos(360/(Segments-1))
  5476.     Radius, Axis, D, Angle : float;
  5477.     ProjU, ProjV : Float_Array;
  5478.     N : integer;
  5479.     Invalid_Operation : exception;
  5480.   begin
  5481.     Axis := 1.0;
  5482.     Case Projection is
  5483.       when Orthographic =>
  5484.         Radius := 1.0;
  5485.       when Satellite    =>
  5486.         D      := Proj_Params.Sat_Altitude / 3444.0;
  5487.         Radius := D * Sat_Scale(Proj_Params.Sat_Altitude,
  5488.                                 Proj_Params.View_Altitude)
  5489.                     * ASin(1.0/(D+1.0));
  5490.       when Lambert      =>
  5491.         Radius := 2.0;
  5492.       when Azimuthal    =>
  5493.         Radius := Pi;
  5494.       when others       =>
  5495.         raise Invalid_Operation;
  5496.     end case;
  5497.     ProjU(1) := Radius;
  5498.     ProjV(1) := 0.0;
  5499.     N := 1;
  5500.     Angle := 0.0;
  5501.     Set_Mode(Graphics);
  5502.     Set_Color(Map_Color.Map_Outline);
  5503.     for I in 1 .. Segments loop
  5504.       N := N + 1;
  5505.       Angle    := Angle + 0.087266462;
  5506.       ProjU(N) := Radius*Cos(Angle);
  5507.       ProjV(N) := Radius*Sin(Angle);
  5508.       if N = Max_Points then
  5509.         Graff(N, ProjU, ProjV, 1);
  5510.         ProjU(1) := ProjU(N);
  5511.         ProjV(1) := ProjV(N);
  5512.         N := 1;
  5513.       end if;
  5514.     end loop;
  5515.     if N /= 1 then
  5516.       Graff(N, ProjU, ProjV, 1);
  5517.     end if;
  5518.     Set_Mode(Text);
  5519.   exception
  5520.     when Invalid_Operation => N := 0; -- null;
  5521.   end Draw_Limb;
  5522.  
  5523.   procedure Draw_Grids is
  5524.   -- Draws the grid lines on the map.
  5525.     Grid_Rec     : constant Grid_Line_Parameters
  5526.                      := World_Menus.Current_Grid_Line_Parameters;
  5527.     Lat_Initial  : constant float   :=  -90.0;
  5528.     Lat_Final    : constant float   :=   89.0;
  5529.     Lon_Initial  : constant float   := -180.0;
  5530.     Lon_Final    : constant float   :=  180.0;
  5531.     Increment    : constant float   := Grid_Rec.Segment_Length;
  5532.     Grid_Lat     : constant float   := Grid_Rec.Degrees_Btwn_Lats;
  5533.     Grid_Lon     : constant float   := Grid_Rec.Degrees_Btwn_Lons;
  5534.     S_Lat        : constant float   :=    7.5;
  5535.     A_Lon        : constant integer :=   90;
  5536.     ProjU, ProjV : Float_Array;
  5537.     X_Lat, X_Lon : float;
  5538.     Lat_Stop     : float;
  5539.     NPts         : integer;
  5540.  
  5541.     procedure Reset is
  5542.     begin
  5543.       NPts := 0;
  5544.       if integer(X_Lon) mod A_Lon = 0 then
  5545.         X_Lat    := Lat_Initial + S_Lat;
  5546.         Lat_Stop := Lat_Final   - S_Lat;
  5547.       else
  5548.         X_Lat    := Lat_Initial;
  5549.         Lat_Stop := Lat_Final;
  5550.       end if;
  5551.     end Reset;
  5552.  
  5553.   begin  -- Draw_Grids
  5554.     Set_Mode(Graphics);
  5555.     Set_Color(Map_Color.Grid_Lines);
  5556.     if Grid_Lat /= 0.0 then
  5557.       X_Lat := Lat_Initial + Grid_Lat;
  5558.       X_Lon := Lon_Initial;
  5559.       NPts  := 0;
  5560.       loop
  5561.         NPts := NPts + 1;
  5562.         Project(X_Lat, X_Lon, ProjU(NPts), ProjV(NPts));
  5563.         X_Lon := X_Lon + Increment;
  5564.         if X_Lon > Lon_Final then
  5565.           Graff(NPts, ProjU, ProjV, 3);
  5566.           X_Lat := X_Lat + Grid_Lat;
  5567.           exit when X_Lat > Lat_Final;
  5568.           X_Lon := Lon_Initial;
  5569.           NPts  := 0;
  5570.         end if;
  5571.       end loop;
  5572.     end if;
  5573.     if Grid_Lon /= 0.0 then
  5574.       X_Lon := Lon_Initial + Grid_Lon;
  5575.       Reset;
  5576.       loop
  5577.         NPts := NPts + 1;
  5578.         Project(X_Lat, X_Lon, ProjU(NPts), ProjV(NPts));
  5579.         X_Lat := X_Lat + Increment;
  5580.         if X_Lat > Lat_Stop then
  5581.           Graff(NPts, ProjU, ProjV, 3);
  5582.           X_Lon := X_Lon + Grid_Lon;
  5583.           exit when X_Lon > Lon_Final;
  5584.           Reset;
  5585.         end if;
  5586.       end loop;
  5587.     end if;
  5588.     Set_Mode(Text);
  5589.   end Draw_Grids;
  5590.  
  5591. begin  -- Draw_Map
  5592.   Proj_Params := World_Menus.Current_Projection_Parameters;
  5593.   Initialize_Plot;
  5594.   if Plot_Land then
  5595.     Plot_Points(Map_Data, Specials.Points_Last,
  5596.                 Specials.Points_Data, Specials.Points_Color);
  5597.   end if;
  5598.   Draw_Limb;
  5599.   if Show_Grid then
  5600.     Draw_Grids;
  5601.   end if;
  5602.   if Show_Beam then
  5603.     Plot_Points(Beam_Data, Specials.Beam_Last,
  5604.                 Specials.Beam_Data,  Specials.Beam_Color);
  5605.   end if;
  5606.   if Show_Swath then
  5607.     Plot_Points(Symbol_Data, Specials.Swath_Last,
  5608.                 Specials.Swath_Data, Specials.Swath_Color);
  5609.   end if;
  5610. exception
  5611.   when Caught_Error     =>
  5612.     null;
  5613.   when Constraint_Error =>
  5614.     Menu_Draw.Draw_Error_Port("Constraint Error", "");
  5615.   when Numeric_Error    =>
  5616.     Menu_Draw.Draw_Error_Port("Numeric Error", "");
  5617.   when Storage_Error    =>
  5618.     Menu_Draw.Draw_Error_Port("Storage Error", "");
  5619.   when Tasking_Error    =>
  5620.     Menu_Draw.Draw_Error_Port("Tasking Error", "");
  5621.   when others => null;
  5622.     Menu_Draw.Draw_Error_Port("Unknown Error", "");
  5623. end Draw_Map;
  5624.  
  5625. begin -- World_Map
  5626.   null;
  5627. end World_Map;
  5628. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5629. --world.txt
  5630. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5631. with Text_Io, Graphic, World_Menus, World_Map;
  5632. use  Text_Io, Graphic, World_Menus, World_Map;
  5633. procedure World is
  5634.   Map : View_Port;
  5635. begin
  5636.   World_Menus.Initialize;
  5637.   Create_Port( Map, 0, 1, 132, 22 );
  5638.   loop
  5639.     Generate_Menus;
  5640.     exit when End_Of_Session;
  5641.     Select_Port(Map);
  5642.     Draw_Map;
  5643.   end loop;  
  5644. end World;
  5645. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5646. --grprntrnx.txt
  5647. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5648. with text_io; use text_io;
  5649. package body Graphic is
  5650. -- This body was written for use on a Printronix 300 printer.
  5651.  
  5652. --Required constants for all versions.
  5653.   Screen_X_Max  : constant Pixel := 650;
  5654.   Screen_Y_Max  : constant Pixel := 650;
  5655.   Y_To_X_Ratio  : constant float := 1.2;
  5656.  
  5657. --Required variables for all versions.
  5658.   X_Text_To_Bit : float     := 6.0;
  5659.   Y_Text_To_Bit : float     := 12.0;
  5660.   Draw_Port     : View_Port := null;
  5661.   Epsilon : constant float := 1.0e-15;
  5662.  
  5663. --Printronix 300 stuff.
  5664.  
  5665.   type Pixel_Value is (Off, On);
  5666.  
  5667. --  type Screen_Type is array (0..Screen_Y_Max,
  5668. --                             0..Screen_X_Max) of Pixel_Value;
  5669. --  type Screen_Ptr  is access Screen_Type;
  5670. --
  5671. --  Screen : Screen_Ptr;
  5672.  
  5673.   type Screen_Type is array ( 0 .. Screen_Y_Max ) of Pixel_Value;
  5674.   type Big_array_Ptr is access Screen_Type;
  5675.  
  5676.   type Screen_ptr is array ( 0 .. Screen_X_Max ) of Big_Array_Ptr;
  5677.  
  5678.   Screen : Screen_Ptr;
  5679.   empty_column : constant screen_type := ( 0 .. Screen_Y_Max => Off );
  5680.  
  5681. function Less_Than(A, B: Coordinate) return boolean is
  5682. begin
  5683.   if abs(A-B) < Epsilon then
  5684.     return false;      --because that's close enough to being equal
  5685.   else
  5686.     return A < B;
  5687.   end if;
  5688. end Less_Than;
  5689.  
  5690. function Greater_Than(A, B: Coordinate) return boolean is
  5691. begin
  5692.   if abs(A-B) < Epsilon then
  5693.     return false;      --because that's close enough to being equal
  5694.   else
  5695.     return A > B;
  5696.   end if;
  5697. end Greater_Than;
  5698.  
  5699. function Equals(A, B: Coordinate) return boolean is
  5700. begin
  5701.   if abs(A-B) < Epsilon then
  5702.     return true;      --because that's close enough to being equal
  5703.   else
  5704.     return false;
  5705.   end if;
  5706. end Equals;
  5707.  
  5708. function Adjust_Y_To_Screen(Y : in integer) return integer is
  5709. -- Isolate the dependency of a terminal's origin location.  TRNX
  5710. -- assumes (0,0) in lower left corner.  If it is a bad assumption,
  5711. -- it is corrected here.
  5712. begin
  5713.   -- for terminals with (0,0) in upper left corner (VT241)
  5714.   -- use
  5715.   -- return Screen_Y_Max - Y;
  5716.  
  5717.   -- for terminals with (0,0) in lower left corner (Printronix 300)
  5718.   -- use
  5719.      return Y;
  5720. end Adjust_Y_To_Screen;
  5721.  
  5722. procedure Redefine(Port: in out View_Port;
  5723.                    Left, Top, Width, Height: in Coordinate) is
  5724.  
  5725.   procedure Verify(Value, Max: in Pixel) is
  5726.   -- verify Value to be between Min and Max.
  5727.   begin
  5728.     if Value < 0 or Value > Max then
  5729.       raise Value_Off_Screen;
  5730.     end if;
  5731.   end Verify;
  5732.  
  5733. begin  -- Redefine
  5734.   Port.Color  := 1.0;   -- start with white
  5735.   Port.Window_Defined := false;
  5736.   Port.Left   := integer(Left*X_Text_To_Bit);
  5737.   Port.Right  := Port.Left + integer(Width*X_Text_To_Bit) - 1;
  5738.   Port.Top    := Screen_Y_Max -  integer(Top*Y_Text_To_Bit);
  5739.   Port.Bottom := Screen_Y_Max - (integer((Top+Height)*Y_Text_To_Bit)-1);
  5740.   Verify(Port.Left,   Screen_X_Max);
  5741.   Verify(Port.Right,  Screen_X_Max);
  5742.   Verify(Port.Top,    Screen_Y_Max);
  5743.   Verify(Port.Bottom, Screen_Y_Max);
  5744.   Draw_Port := Port;
  5745. end Redefine;
  5746.  
  5747. procedure Redefine(Port: in out View_Port;
  5748.                    Left, Top, Width, Height: in integer) is
  5749. begin
  5750.   Redefine(Port, float(Left), float(Top), float(Width), float(Height));
  5751. end Redefine;
  5752.  
  5753. procedure Create_Port(Port: in out View_Port;
  5754.                       Left, Top, Width, Height: in Coordinate) is
  5755. begin
  5756.   Port := new V_Port;
  5757.   Redefine(Port, Left, Top, Width, Height);
  5758. end Create_Port;
  5759.  
  5760. procedure Create_Port(Port: in out View_Port;
  5761.                       Left, Top, Width, Height: in integer) is
  5762. begin
  5763.   Create_Port(Port, float(Left), float(Top), float(Width), float(Height));
  5764. end Create_Port;
  5765.  
  5766. procedure New_Screen_Size(Columns, Lines : in integer) is
  5767. -- Set X_Text_To_Bit and Y_Text_To_Bit to coorespond to a given screen size.
  5768. -- This routine should only have an affect on terminal with varying text
  5769. -- screens.  If Columns and Lines passed do not match some configuration
  5770. -- available on the terminal, Illegal_Screen_Size is raised.
  5771. begin
  5772.   if Columns /= 132 then
  5773.     raise Illegal_Screen_Size;
  5774.   end if;
  5775.   case Lines is
  5776.     when     66 => Y_Text_To_Bit := 12.0;
  5777.     when     88 => Y_Text_To_Bit :=  9.0;
  5778.     when    110 => Y_Text_To_Bit :=  7.2;
  5779.     when others => raise Illegal_Screen_Size;
  5780.   end case;
  5781. end New_Screen_Size;
  5782.  
  5783. procedure Window_To_Pixel(Window_X, Window_Y : in Coordinate;
  5784.                           Pixel_X,  Pixel_Y  : in out Pixel) is
  5785. -- Translate a window coordinate to a pixel coordinate through the current
  5786. -- drawing port.  If the current drawing port's window has not been defined,
  5787. -- the Undefined_Window exception is raised.
  5788. begin
  5789.   if Draw_Port.Window_Defined then
  5790.     Pixel_X := integer(Window_X * Draw_Port.X_Scale + Draw_Port.X_Shift);
  5791.     Pixel_Y := Adjust_Y_To_Screen(
  5792.                  integer(Window_Y * Draw_Port.Y_Scale + Draw_Port.Y_Shift) );
  5793.   else
  5794.     raise Undefined_Window;
  5795.   end if;
  5796. end Window_To_Pixel;
  5797.  
  5798. procedure Set_Window(Left, Bottom, Right, Top: in Coordinate) is
  5799. -- Defines the world coordinates to be seen through the current View_Port.
  5800. -- If either the width or Height is zero, Set_Window will define them
  5801. -- such that the aspect ratio is sqaure (cause circles to be round).
  5802. -- If both are zero, the Zero_Area exception is raised.
  5803.   Aspect_Ratio : float;
  5804.   Half_Size    : float;      -- Half the X or Y world size of the view port
  5805.   L, B, R, T   : Coordinate; -- Copies of the input parameters
  5806.  
  5807.   function Min(A, B: Coordinate) return Coordinate is
  5808.   begin
  5809.     if A < B then
  5810.       return A;
  5811.     else
  5812.       return B;
  5813.     end if;
  5814.   end Min;
  5815.  
  5816.   function Max(A, B: Coordinate) return Coordinate is
  5817.   begin
  5818.     if A > B then
  5819.       return A;
  5820.     else
  5821.       return B;
  5822.     end if;
  5823.   end Max;
  5824.  
  5825. begin  -- Set_Window
  5826.   if Equals(Left, Right) and Equals(Bottom, Top) then
  5827.     raise Zero_Area;
  5828.   else
  5829.     L := Left;
  5830.     B := Bottom;
  5831.     R := Right;
  5832.     T := Top;
  5833.     Aspect_Ratio := Y_To_X_Ratio * float(Draw_Port.Right - Draw_Port.Left) /
  5834.                                    float(Draw_Port.Top - Draw_Port.Bottom);
  5835.     -- Check for zero area in one direction.
  5836.     -- If found, insure a "square" area port
  5837.     if Equals(Left, Right) then
  5838.       Half_Size := (Top - Bottom) * Aspect_Ratio / 2.0;
  5839.       R := R + Half_Size;
  5840.       L := L - Half_Size;
  5841.     elsif Equals(Top, Bottom) then
  5842.       Half_Size := ((Right - Left) / Aspect_Ratio) / 2.0;
  5843.       T := T + Half_Size;
  5844.       B := B - Half_Size;
  5845.     end if;
  5846.     Draw_Port.WX_Min  := Min(L,R);
  5847.     Draw_Port.WY_Min  := Min(B,T);
  5848.     Draw_Port.WX_Max  := Max(L,R);
  5849.     Draw_Port.WY_Max  := Max(B,T);
  5850.     Draw_Port.X_Scale := float(Draw_Port.Right  - Draw_Port.Left)
  5851.                          / (R - L);
  5852.     Draw_Port.Y_Scale := float(Draw_Port.Top - Draw_Port.Bottom)
  5853.                          / (T - B);
  5854.     Draw_Port.X_Shift := float(Draw_Port.Left)   - L * Draw_Port.X_Scale;
  5855.     Draw_Port.Y_Shift := float(Draw_Port.Bottom) - B * Draw_Port.Y_Scale;
  5856.     Draw_Port.X_Current := 0.0;
  5857.     Draw_Port.Y_Current := 0.0;
  5858.     Draw_Port.Window_Defined := true;
  5859.   end if;
  5860. end Set_Window;
  5861.  
  5862. procedure Set_Window(Left, Bottom, Right, Top: in integer) is
  5863. begin
  5864.   Set_Window(float(Left), float(Bottom), float(Right), float(Top));
  5865. end Set_Window;
  5866.  
  5867. function Color_To_Spectrum(Color : Color_Type) return Color_Spectrum is
  5868. -- Convert a Color_Type to a Color_Spectrum.
  5869. begin
  5870.   Case Color is
  5871.     when Black  => return 0.0;
  5872.     when Brown  => return 0.1667;
  5873.     when Blue   => return 0.3333;
  5874.     when Green  => return 0.5;
  5875.     when Yellow => return 0.6667;
  5876.     when Red    => return 0.8333;
  5877.     when White  => return 1.0;
  5878.     when others => null;
  5879.   end case;
  5880. end Color_To_Spectrum;
  5881.  
  5882. function Spectrum_To_Color(Spectrum : in Color_Spectrum) return Color_Type is
  5883. -- Convert a Color_Spectrum to a Color_Type
  5884. begin
  5885.   case integer(Spectrum*10.0) is
  5886.     when 0      => return Black;
  5887.     when 1..2   => return Brown;
  5888.     when 3      => return Blue;
  5889.     when 4..5   => return Green;
  5890.     when 6..7   => return Yellow;
  5891.     when 8..9   => return Red;
  5892.     when 10     => return White;
  5893.     when others => null;
  5894.   end case;
  5895. end Spectrum_To_Color;
  5896.  
  5897. function Color_Char(Color : Color_Spectrum) return character is
  5898.   Color_String : constant string(1..7) := "DDBGYRW";
  5899.   Color_Index  : integer;
  5900. begin
  5901.   Color_Index := 1 + Color_Type'pos(Spectrum_To_Color(Color));
  5902.   return Color_String(Color_Index);
  5903. end Color_Char;
  5904.  
  5905. procedure Draw_Line(Start_WX, Start_WY, End_WX, End_WY : in Coordinate;
  5906.                     Color : in Color_Spectrum) is
  5907. -- Draws a line segment from (Start_WX, Start_WY) to (End_WX, End_WY).  No
  5908. -- clipping is performed.
  5909.   Start_PX, Start_PY, End_PX, End_PY : Pixel;
  5910.  
  5911.   procedure Draw_Segment(Sx, Sy, Ex, Ey : in integer;
  5912.                          Color : in Color_Spectrum) is
  5913.   -- Printronix 300 dependent.  Will draw a line segment from (Sx,Sy) to
  5914.   -- (Ex,Ey) of Color.  Algorithm taken from Newman and Sproull.
  5915.     Y_Length, Length, I : integer;
  5916.     X, Y, X_Increment, Y_Increment : float;
  5917.     Zero_Length : exception;
  5918.     Pixel_Color : Pixel_Value;
  5919.   begin
  5920.     if Color = 0.0 then
  5921.       Pixel_Color := Off;
  5922.     else
  5923.       Pixel_Color := On;
  5924.     end if;
  5925.     Length := abs(Ex - Sx);
  5926.     Y_Length := abs(Ey - Sy);
  5927.     if Y_Length >= Length then
  5928.       if Y_Length = 0 then
  5929.         Screen(Sy)(Sx) := On;
  5930.         raise Zero_Length;
  5931.       end if;
  5932.       Length := abs(Ey - Sy);
  5933.     end if;
  5934.     X_Increment := float(Ex - Sx) / float(Length);
  5935.     Y_Increment := float(Ey - Sy) / float(Length);
  5936.     X := float(Sx);
  5937.     Y := float(Sy);
  5938.     for I in 1 .. Length loop
  5939.       Screen(integer(Y))(integer(X)) := Pixel_Color;
  5940.       X := X + X_Increment;
  5941.       Y := Y + Y_Increment;
  5942.     end loop;
  5943.   exception
  5944.     when Zero_Length => null;
  5945.   end Draw_Segment;
  5946.  
  5947. begin  --Draw_Line
  5948.   Window_To_Pixel(Start_WX, Start_WY, Start_PX, Start_PY);
  5949.   Window_To_Pixel(End_WX, End_WY, End_PX, End_PY);
  5950.   Draw_Segment(Start_PX, Start_Py, End_PX, End_PY, Color);
  5951. end Draw_Line;
  5952.  
  5953. procedure Select_Port(Port: in View_Port) is
  5954. -- Select a different port to draw in.
  5955. begin
  5956.   Draw_Port := Port;
  5957. end Select_Port;
  5958.  
  5959. procedure Erase_Screen is
  5960. -- A quick way to erase all TRNXs on the screen.
  5961. begin
  5962.   -- Printronix 300 dependent.
  5963.   Put_Line("Erasing screen");
  5964.   for Row in 0 .. Screen_X_Max loop
  5965.       Screen(Row)( 0 .. Screen_Y_Max ) := Empty_Column;
  5966.   end loop;
  5967.   Put_Line("Erasing complete");
  5968. end Erase_Screen ;
  5969.  
  5970. procedure Erase_Port(Color : in Color_Type) is
  5971. -- Erase the port currently being drawn in.
  5972. begin
  5973.   Erase_Port(Draw_Port, Color_To_Spectrum(Color));
  5974. end Erase_Port ;
  5975.  
  5976. procedure Erase_Port(Color : in Color_Spectrum := 0.0) is
  5977. -- Erase the port currently being drawn in.
  5978. begin
  5979.   Erase_Port(Draw_Port, Color);
  5980. end Erase_Port ;
  5981.  
  5982. procedure Erase_Port(Port: in View_Port; Color : in Color_Type) is
  5983. -- Erase a specified port.
  5984. begin
  5985.   Erase_Port(Port, Color_To_Spectrum(Color));
  5986. end Erase_Port;
  5987.  
  5988. procedure Erase_Port(Port: in View_Port; Color : in Color_Spectrum := 0.0) is
  5989. -- Erase a specified port.
  5990.   Pixel_Color : Pixel_Value;
  5991. begin
  5992.   -- Printronix 300.
  5993.    if Color = 0.0 then
  5994.      Pixel_Color := Off;
  5995.    else
  5996.      Pixel_Color := On;
  5997.    end if;
  5998.   for Row in Port.Top .. Port.Bottom loop
  5999.     for Col in Port.Left .. Port.Right loop
  6000.       Screen(Row)(Col) := Pixel_Color;
  6001.     end loop;
  6002.   end loop;
  6003. end Erase_Port;
  6004.  
  6005. procedure Frame_Port is
  6006. -- Draw a frame around the port currently being drawn in.
  6007. begin
  6008.   Draw_Line(Draw_Port.WX_Min, Draw_Port.WY_Min,
  6009.             Draw_Port.WX_Max, Draw_Port.WY_Min, Draw_Port.Color);
  6010.   Draw_Line(Draw_Port.WX_Max, Draw_Port.WY_Min,
  6011.             Draw_Port.WX_Max, Draw_Port.WY_Max, Draw_Port.Color);
  6012.   Draw_Line(Draw_Port.WX_Max, Draw_Port.WY_Max,
  6013.             Draw_Port.WX_Min, Draw_Port.WY_Max, Draw_Port.Color);
  6014.   Draw_Line(Draw_Port.WX_Min, Draw_Port.WY_Max,
  6015.             Draw_Port.WX_Min, Draw_Port.WY_Min, Draw_Port.Color);
  6016. end Frame_Port ;
  6017.  
  6018. procedure Move_To(New_X, New_Y: in Coordinate) is
  6019. -- Move the drawing start position to the absolute coordinates (New_X, New_Y).
  6020. begin
  6021.   Draw_Port.X_Current := New_X;
  6022.   Draw_Port.Y_Current := New_Y;
  6023. end Move_To;
  6024.  
  6025. procedure Move_To(New_X, New_Y: in integer) is
  6026. begin
  6027.   Draw_Port.X_Current := float(New_X);
  6028.   Draw_Port.Y_Current := float(New_Y);
  6029. end Move_To;
  6030.  
  6031. procedure Move(Delta_X, Delta_Y: in Coordinate) is
  6032. -- Change the drawing start position by Delta_X and Delta_Y.
  6033. begin
  6034.   Move_To( Draw_Port.X_Current + Delta_X,
  6035.            Draw_Port.Y_Current + Delta_Y );
  6036. end Move;
  6037.  
  6038. procedure Move(Delta_X, Delta_Y: in integer) is
  6039. begin
  6040.   Move_To( Draw_Port.X_Current + float(Delta_X),
  6041.            Draw_Port.Y_Current + float(Delta_Y));
  6042. end Move;
  6043.  
  6044. procedure Clip(X1, Y1, X2, Y2: in out Coordinate; In_View: in out boolean) is
  6045. -- Given an imaginary line segment between the coordinates (X1,Y1) and
  6046. -- (X2, Y2), insure that they are within the current View_Port.
  6047. -- In_View is returned false iff the line segment lies completely outside of
  6048. -- the View_Port.
  6049. -- The algorithm is taken from Newman and Sproull, Principles of Interactive
  6050. -- Computer TRNXs pp. 66-67.
  6051. type Edge is (Left, Bottom, Right, Top);
  6052. type Edge_Set is array(Left..Top) of boolean;
  6053.   yy : Edge;
  6054.   C, C1, C2 : Edge_Set;
  6055.   X, Y : Coordinate;
  6056.   None : constant Edge_Set := Edge_Set'(others => false);
  6057.   Off_Screen_Completely : exception;
  6058.  
  6059.   procedure Code(X, Y: in Coordinate; C: out Edge_Set) is
  6060.   begin
  6061.     C := None;
  6062.     if Less_Than(X, Draw_Port.WX_Min) then
  6063.       C(Left) := true;
  6064.     elsif Greater_Than(X, Draw_Port.WX_Max) then
  6065.       C(Right) := true;
  6066.     end if;
  6067.     if Less_Than(Y, Draw_Port.WY_Min) then
  6068.       C(Bottom) := true;
  6069.     elsif Greater_Than(Y, Draw_Port.WY_Max) then
  6070.       C(Top) := true;
  6071.     end if;
  6072.   end Code;
  6073.  
  6074.   function C1_and_C2_ne_None return boolean is
  6075.   -- make up for compiler bug.
  6076.     Result : boolean := false;
  6077.     I      : Edge;
  6078.   begin
  6079.     I := Left;
  6080.     loop
  6081.       if C1(I) and C2(I) then
  6082.         Result := true;
  6083.         exit;
  6084.       end if;
  6085.       exit when I = Top;
  6086.       I := Edge'Succ(I);
  6087.     end loop;
  6088.     return Result;
  6089.   end C1_and_C2_ne_None;
  6090.  
  6091. begin  -- Clip
  6092.   Code(X1, Y1, C1);
  6093.   Code(X2, Y2, C2);
  6094.   while (C1 /= None) or (C2 /= None) loop
  6095.     if C1_and_C2_ne_None then
  6096.       raise Off_Screen_Completely;
  6097.     end if;
  6098.     C := C1;
  6099.     if C = None then
  6100.       C := C2;
  6101.     end if;
  6102.     if C(Left) then       -- Crosses left   edge
  6103.       Y := Y1 + (Y2 - Y1) * (Draw_Port.WX_Min - X1) / (X2 - X1);
  6104.       X := Draw_Port.WX_Min;
  6105.     elsif C(Bottom) then  -- Crosses bottom edge
  6106.       X := X1 + (X2 - X1) * (Draw_Port.WY_Min - Y1) / (Y2 - Y1);
  6107.       Y := Draw_Port.WY_Min;
  6108.     elsif C(Right) then   -- Crosses right  edge
  6109.       Y := Y1 + (Y2 - Y1) * (Draw_Port.WX_Max - X1) / (X2 - X1);
  6110.       X := Draw_Port.WX_Max;
  6111.     elsif C(Top) then     -- Crosses top    edge
  6112.       X := X1 + (X2 - X1) * (Draw_Port.WY_Max - Y1) / (Y2 - Y1);
  6113.       Y := Draw_Port.WY_Max;
  6114.     end if;
  6115.     if C = C1 then
  6116.       X1 := X;
  6117.       Y1 := Y;
  6118.       Code(X, Y, C1);
  6119.     else
  6120.       X2 := X;
  6121.       Y2 := Y;
  6122.       Code(X, Y, C2);
  6123.     end if;
  6124.   end loop;
  6125.   In_View := true;
  6126. exception
  6127.   when Off_Screen_Completely => In_View := false;
  6128. end Clip;
  6129.  
  6130. procedure Line_To(New_X, New_Y: in Coordinate) is
  6131. -- Draw a line from the drawing start position to the absolute coordinates
  6132. -- (New_X, New_Y).
  6133.   SX, SY, EX, EY : Coordinate;
  6134.   Drawable : boolean;
  6135. begin
  6136.   SX := Draw_Port.X_Current;
  6137.   SY := Draw_Port.Y_Current;
  6138.   EX := New_X;
  6139.   EY := New_Y;
  6140.   Clip(SX, SY, EX, EY, Drawable);
  6141.   if Drawable then
  6142.     Draw_Line(SX, SY, EX, EY, Draw_Port.Color);
  6143.   end if;
  6144.   Draw_Port.X_Current := New_X;
  6145.   Draw_Port.Y_Current := New_Y;
  6146. end Line_To;
  6147.  
  6148. procedure Line_To(New_X, New_Y: in integer) is
  6149. begin
  6150.   Line_To(float(New_X), float(New_Y));
  6151. end Line_To;
  6152.  
  6153. procedure Line(Delta_X, Delta_Y: in Coordinate) is
  6154. -- Draw a line from the drawing start position to the point Delta_X and
  6155. -- Delta_Y away.
  6156. begin
  6157.   Line_To( Draw_Port.X_Current + Delta_X,
  6158.            Draw_Port.Y_Current + Delta_Y );
  6159. end Line;
  6160.  
  6161. procedure Line(Delta_X, Delta_Y: in integer) is
  6162. begin
  6163.   Line_To( Draw_Port.X_Current + float(Delta_X),
  6164.            Draw_Port.Y_Current + float(Delta_Y));
  6165. end Line;
  6166.  
  6167. procedure Set_Color(Color_Code: in Color_Spectrum) is
  6168. -- Change the drawing color to Color_Code returning the previous color.
  6169. -- The Color_Spectrum is defined to range from 0.0 (black) to 1.0 (white).
  6170. -- Any color code outside that range will cause Illegal_Color exception to 
  6171. -- be raised.
  6172. begin
  6173.   if Color_Code < 0.0 or Color_Code > 1.0 then
  6174.     raise Illegal_Color;
  6175.   else
  6176.     Draw_Port.Color := Color_Code;
  6177.   end if;
  6178. end Set_Color;
  6179.  
  6180. function Set_Color(Color_Code: in Color_Spectrum) return Color_Spectrum is
  6181.   Old_Color_Code : Color_Spectrum := Draw_Port.Color;
  6182. begin
  6183.   Set_Color(Color_Code);
  6184.   return Old_Color_Code;
  6185. end Set_Color;
  6186.  
  6187. procedure Set_Color(Color: in Color_Type) is
  6188. begin
  6189.   Set_Color(Color_To_Spectrum(Color));
  6190. end Set_Color;
  6191.  
  6192. function Set_Color(Color: in Color_Type) return Color_Type is
  6193.   Old_Color : Color_Type := Spectrum_To_Color(Draw_Port.Color);
  6194. begin
  6195.   Set_Color(Color_To_Spectrum(Color));
  6196.   return Old_Color;
  6197. end Set_Color;
  6198.  
  6199. procedure Where_Am_I(Current_X, Current_Y: out Coordinate) is
  6200. begin
  6201.   Current_X := Draw_Port.X_Current;
  6202.   Current_Y := Draw_Port.Y_Current;
  6203. end Where_Am_I;
  6204.  
  6205. procedure Set_Mode(Mode: in Terminal_Mode) is
  6206. begin
  6207.   null;
  6208. end Set_Mode;
  6209.  
  6210. procedure Print_Screen(File_Name : String) is
  6211. -- Put the screen to a file for output to a TRNX printer.
  6212. -- This implementation is Printronix 300 dependent.
  6213.   Trnx_Line_Designator : constant character := character'val(5);
  6214.   F         : File_Type;
  6215.   Col, Line : integer;
  6216.   Int_Byte  : integer;
  6217.   Trnx_Line : String(1 .. 134);
  6218.   Last_Char : integer;
  6219.   Last_Non_Blank : integer;
  6220.   Dot       : integer := 0;
  6221. begin
  6222.   Create(F, Out_File, File_Name, "");
  6223.   for Line in reverse 0 .. Screen_Y_Max loop
  6224.     if Line mod 50 = 0 then
  6225.       new_line;
  6226.     end if;
  6227.     put('.');
  6228.     Last_Char := 0;
  6229.     Last_Non_Blank := 0;
  6230.     Col := 0;
  6231.     loop
  6232.       Int_Byte := 1;
  6233.       for Bit in reverse 0..5 loop
  6234.         Int_Byte := Int_Byte * 2;
  6235.         if Screen(Line)(Col+Bit) = On then
  6236.           Int_Byte := Int_Byte + 1;
  6237.         end if;
  6238.       end loop;
  6239.       Last_Char := Last_Char + 1;
  6240.       if Int_Byte /= 64 then
  6241.         Last_Non_Blank := Last_Char;
  6242.       end if;
  6243.       Trnx_Line(Last_Char) := character'Val(Int_Byte);
  6244.       Col := Col + 6;
  6245.       exit when Col > Screen_X_Max;
  6246.     end loop;
  6247.     if Last_Non_Blank < Last_Char then
  6248.       Last_Char := Last_Non_Blank;
  6249.     end if;
  6250.     Last_Char := Last_Char + 1;
  6251.     Trnx_Line(Last_Char) := TRNX_Line_Designator;
  6252.     Put_Line(F, Trnx_Line(1..Last_Char));
  6253.   end loop;
  6254.   Close(F);
  6255. end Print_Screen;
  6256.  
  6257. function What_Port return View_Port is
  6258. begin
  6259.   return Draw_Port;
  6260. end What_Port;
  6261.  
  6262. begin  -- Printronix 300 initialization
  6263.   for I in 0 .. Screen_Y_Max loop
  6264.     Screen(I) := new Screen_Type;
  6265.   end loop;
  6266.   Erase_Screen;
  6267. end Graphic;
  6268. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6269. --grvt240.txt
  6270. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6271. with text_io; use text_io;
  6272. package body Graphic is
  6273. -- This is the VT240 body.
  6274.  
  6275. --Required constants for all versions.
  6276.   Screen_X_Max  : constant Pixel := 799;
  6277.   Screen_Y_Max  : constant Pixel := 479;
  6278.   Y_To_X_Ratio  : constant float := 1.0;
  6279.   Epsilon       : constant float := 1.0E-15; -- for math operations, telesoft ada.
  6280.  
  6281. --Required variables for all versions.
  6282.   X_Text_To_Bit : float         := 10.0;
  6283.   Y_Text_To_Bit : float         := 20.0;
  6284.   Draw_Port     : View_Port     := null;
  6285.   System_Mode   : Terminal_Mode := Text;
  6286.  
  6287. --Required terminal dependendent variables
  6288.   TT : File_Type;
  6289.   subtype Intens_Type is string(1..4);
  6290.   Old_Intensity  : Intens_Type := "????";
  6291.   Last_X, Last_Y : integer   := integer'first;
  6292.  
  6293. function Less_Than(A, B: Coordinate) return boolean is
  6294. begin
  6295.   if abs(A-B) < Epsilon then
  6296.     return false;      --because that's close enough to being equal
  6297.   else
  6298.     return A < B;
  6299.   end if;
  6300. end Less_Than;
  6301.  
  6302. function Greater_Than(A, B: Coordinate) return boolean is
  6303. begin
  6304.   if abs(A-B) < Epsilon then
  6305.     return false;      --because that's close enough to being equal
  6306.   else
  6307.     return A > B;
  6308.   end if;
  6309. end Greater_Than;
  6310.  
  6311. function Equals(A, B: Coordinate) return boolean is
  6312. begin
  6313.   if abs(A-B) < Epsilon then
  6314.     return true;      --because that's close enough to being equal
  6315.   else
  6316.     return false;
  6317.   end if;
  6318. end Equals;
  6319.  
  6320. function Adjust_Y_To_Screen(Y : in integer) return integer is
  6321. -- Isolate the dependency of a terminal's origin location.  Graphic
  6322. -- assumes (0,0) in lower left corner.  If it is a bad assumption,
  6323. -- it is corrected here.
  6324. begin
  6325.   -- for terminals with (0,0) in upper left corner (VT241)
  6326.   -- use
  6327.      return Screen_Y_Max - Y;
  6328.  
  6329.   -- for terminals with (0,0) in lower left corner (Printronix 300)
  6330.   -- use
  6331.   -- return Y;
  6332. end Adjust_Y_To_Screen;
  6333.  
  6334. procedure Redefine(Port: in out View_Port;
  6335.                    Left, Top, Width, Height: in Coordinate) is
  6336.  
  6337.   procedure Verify(Value, Max: in Pixel) is
  6338.   -- verify Value to be between Min and Max.
  6339.   begin
  6340.     if Value < 0 or Value > Max then
  6341.       raise Value_Off_Screen;
  6342.     end if;
  6343.   end Verify;
  6344.  
  6345. begin  -- Redefine
  6346.   Port.Color  := 1.0;   -- start with white
  6347.   Port.Window_Defined := false;
  6348.   Port.Left   := integer(Left*X_Text_To_Bit);
  6349.   Port.Right  := Port.Left + integer(Width*X_Text_To_Bit) - 1;
  6350.   Port.Top    := Screen_Y_Max -  integer(Top*Y_Text_To_Bit);
  6351.   Port.Bottom := Screen_Y_Max - (integer((Top+Height)*Y_Text_To_Bit)-1);
  6352.   Verify(Port.Left,   Screen_X_Max);
  6353.   Verify(Port.Right,  Screen_X_Max);
  6354.   Verify(Port.Top,    Screen_Y_Max);
  6355.   Verify(Port.Bottom, Screen_Y_Max);
  6356.   Draw_Port := Port;
  6357. end Redefine;
  6358.  
  6359. procedure Redefine(Port: in out View_Port;
  6360.                    Left, Top, Width, Height: in integer) is
  6361. begin
  6362.   Redefine(Port, float(Left), float(Top), float(Width), float(Height));
  6363. end Redefine;
  6364.  
  6365. procedure Create_Port(Port: in out View_Port;
  6366.                       Left, Top, Width, Height: in Coordinate) is
  6367. begin
  6368.   Port := new V_Port;
  6369.   Redefine(Port, Left, Top, Width, Height);
  6370. end Create_Port;
  6371.  
  6372. procedure Create_Port(Port: in out View_Port;
  6373.                       Left, Top, Width, Height: in integer) is
  6374. begin
  6375.   Create_Port(Port, float(Left), float(Top), float(Width), float(Height));
  6376. end Create_Port;
  6377.  
  6378. procedure New_Screen_Size(Columns, Lines : in integer) is
  6379. -- Set X_Text_To_Bit and Y_Text_To_Bit to coorespond to a given screen size.
  6380. -- This routine should only have an affect on terminal with varying text
  6381. -- screens.  If Columns and Lines passed do not match some configuration
  6382. -- available on the terminal, Illegal_Screen_Size is raised.
  6383. -- VT240 dependent.
  6384. begin
  6385.   case Columns is
  6386.     when     80 => X_Text_To_Bit := 10.0;
  6387.     when    132 => X_Text_To_Bit :=  6.0;
  6388.     when others => raise Illegal_Screen_Size;
  6389.   end case;
  6390.   if Lines /= 24 then
  6391.     raise Illegal_Screen_Size;
  6392.   end if;
  6393. end New_Screen_Size;
  6394.  
  6395. procedure Window_To_Pixel(Window_X, Window_Y : in Coordinate;
  6396.                           Pixel_X,  Pixel_Y  : in out Pixel) is
  6397. -- Translate a window coordinate to a pixel coordinate through the current
  6398. -- drawing port.  If the current drawing port's window has not been defined,
  6399. -- the Undefined_Window exception is raised.
  6400. begin
  6401.   if Draw_Port.Window_Defined then
  6402.     Pixel_X := integer(Window_X * Draw_Port.X_Scale + Draw_Port.X_Shift);
  6403.     Pixel_Y := Adjust_Y_To_Screen(
  6404.                  integer(Window_Y * Draw_Port.Y_Scale + Draw_Port.Y_Shift) );
  6405.   else
  6406.     raise Undefined_Window;
  6407.   end if;
  6408. end Window_To_Pixel;
  6409.  
  6410. procedure Set_Window(Left, Bottom, Right, Top: in Coordinate) is
  6411. -- Defines the world coordinates to be seen through the current View_Port.
  6412. -- If either the width or Height is zero, Set_Window will define them
  6413. -- such that the aspect ratio is sqaure (cause circles to be round).
  6414. -- If both are zero, the Zero_Area exception is raised.
  6415.   Aspect_Ratio : float;
  6416.   Half_Size    : float;      -- Half the X or Y world size of the view port
  6417.   L, B, R, T   : Coordinate; -- Copies of the input parameters
  6418.  
  6419.   function Min(A, B: Coordinate) return Coordinate is
  6420.   begin
  6421.     if A < B then
  6422.       return A;
  6423.     else
  6424.       return B;
  6425.     end if;
  6426.   end Min;
  6427.  
  6428.   function Max(A, B: Coordinate) return Coordinate is
  6429.   begin
  6430.     if A > B then
  6431.       return A;
  6432.     else
  6433.       return B;
  6434.     end if;
  6435.   end Max;
  6436.  
  6437. begin  -- Set_Window
  6438.   if Equals(Left, Right) and Equals(Bottom, Top) then
  6439.     raise Zero_Area;
  6440.   else
  6441.     L := Left;
  6442.     B := Bottom;
  6443.     R := Right;
  6444.     T := Top;
  6445.     Aspect_Ratio := Y_To_X_Ratio * float(Draw_Port.Right - Draw_Port.Left) /
  6446.                                    float(Draw_Port.Top - Draw_Port.Bottom);
  6447.     -- Check for zero area in one direction.
  6448.     -- If found, insure a "square" area port
  6449.     if Equals(Left, Right) then
  6450.       Half_Size := (Top - Bottom) * Aspect_Ratio / 2.0;
  6451.       R := R + Half_Size;
  6452.       L := L - Half_Size;
  6453.     elsif Equals(Top, Bottom) then
  6454.       Half_Size := ((Right - Left) / Aspect_Ratio) / 2.0;
  6455.       T := T + Half_Size;
  6456.       B := B - Half_Size;
  6457.     end if;
  6458.     Draw_Port.WX_Min  := Min(L,R);
  6459.     Draw_Port.WY_Min  := Min(B,T);
  6460.     Draw_Port.WX_Max  := Max(L,R);
  6461.     Draw_Port.WY_Max  := Max(B,T);
  6462.     Draw_Port.X_Scale := float(Draw_Port.Right  - Draw_Port.Left)
  6463.                          / (R - L);
  6464.     Draw_Port.Y_Scale := float(Draw_Port.Top - Draw_Port.Bottom)
  6465.                          / (T - B);
  6466.     Draw_Port.X_Shift := float(Draw_Port.Left)   - L * Draw_Port.X_Scale;
  6467.     Draw_Port.Y_Shift := float(Draw_Port.Bottom) - B * Draw_Port.Y_Scale;
  6468.     Draw_Port.X_Current := 0.0;
  6469.     Draw_Port.Y_Current := 0.0;
  6470.     Draw_Port.Window_Defined := true;
  6471.   end if;
  6472. end Set_Window;
  6473.  
  6474. procedure Set_Window(Left, Bottom, Right, Top: in integer) is
  6475. begin
  6476.   Set_Window(float(Left), float(Bottom), float(Right), float(Top));
  6477. end Set_Window;
  6478.  
  6479. function Color_To_Spectrum(Color : Color_Type) return Color_Spectrum is
  6480. -- Convert a Color_Type to a Color_Spectrum.
  6481. begin
  6482.   Case Color is
  6483.     when Black  => return 0.0;
  6484.     when Brown  => return 0.1667;
  6485.     when Blue   => return 0.3333;
  6486.     when Green  => return 0.5;
  6487.     when Yellow => return 0.6667;
  6488.     when Red    => return 0.8333;
  6489.     when White  => return 1.0;
  6490.     when others => null;
  6491.   end case;
  6492. end Color_To_Spectrum;
  6493.  
  6494. function Spectrum_To_Color(Spectrum : in Color_Spectrum) return Color_Type is
  6495. -- Convert a Color_Spectrum to a Color_Type
  6496. begin
  6497.   case integer(Spectrum*10.0) is
  6498.     when 0      => return Black;
  6499.     when 1..2   => return Brown;
  6500.     when 3      => return Blue;
  6501.     when 4..5   => return Green;
  6502.     when 6..7   => return Yellow;
  6503.     when 8..9   => return Red;
  6504.     when 10     => return White;
  6505.     when others => null;
  6506.   end case;
  6507. end Spectrum_To_Color;
  6508.  
  6509. function Intensity(Color : Color_Spectrum) return Intens_Type is
  6510. -- VT240 dependent
  6511. begin
  6512.   if Color < 0.25 then
  6513.     return "L0  ";
  6514.   elsif Color < 0.5 then
  6515.     return "L33 ";
  6516.   elsif Color < 0.75 then
  6517.     return "L67 ";
  6518.   else
  6519.     return "L100";
  6520.   end if;
  6521. end Intensity;
  6522.     
  6523. procedure Draw_Segment(Sx, Sy, Ex, Ey : in integer;
  6524.                        Color : in Color_Spectrum) is
  6525. -- Draw a line segment from (Sx,Sy) to (Ex,Ey) of Color.
  6526. -- VT240 dependent
  6527.   New_Intensity : constant Intens_Type := Intensity(Color);
  6528. begin
  6529.   if System_Mode = Text then  -- temporarily change to graphics mode
  6530.     Put(TT, Ascii.Esc); Put(TT, "P1p");
  6531.   end if;
  6532.   if New_Intensity /= Old_Intensity then
  6533.     Put(TT, "W(I(" & New_Intensity & "))");
  6534.     Old_Intensity := New_Intensity;
  6535.   end if;
  6536.   if Sx /= Last_X  or  Sy /= Last_Y then
  6537.     Put(TT, "P[" & integer'image(Sx) & "," & integer'image(Sy) & "]");
  6538.   end if;
  6539.   Put(TT, "V[" & integer'image(Ex) & "," & integer'image(Ey) & "]");
  6540.   New_Line(TT);
  6541.   Last_X := Ex;
  6542.   Last_Y := Ey;
  6543.   if System_Mode = Text then  -- change it back
  6544.     Put(TT, Ascii.Esc); Put(TT, "\");
  6545.   end if;
  6546. end Draw_Segment;
  6547.  
  6548. procedure Draw_Line(Start_WX, Start_WY, End_WX, End_WY : in Coordinate;
  6549.                     Color : in Color_Spectrum) is
  6550. -- Draws a line segment from (Start_WX, Start_WY) to (End_WX, End_WY).  No
  6551. -- clipping is performed.
  6552.   Start_PX, Start_PY, End_PX, End_PY : Pixel;
  6553. begin
  6554.   Window_To_Pixel(Start_WX, Start_WY, Start_PX, Start_PY);
  6555.   Window_To_Pixel(End_WX, End_WY, End_PX, End_PY);
  6556.   Draw_Segment(Start_PX, Start_Py, End_PX, End_PY, Color);
  6557. end Draw_Line;
  6558.  
  6559. procedure Select_Port(Port: in View_Port) is
  6560. -- Select a different port to draw in.
  6561. begin
  6562.   Draw_Port := Port;
  6563. end Select_Port;
  6564.  
  6565. procedure Erase_Screen is
  6566. -- A quick way to erase all graphics on the screen.
  6567. -- VT240 dependent
  6568. begin
  6569.   -- Side effect is all text is erased as well as graphics.
  6570.   if System_Mode = Text then  -- temporarily change to graphics mode
  6571.     Put(TT, Ascii.Esc); Put(TT, "P1p");
  6572.   end if;
  6573.   Put(TT, "S(E)");
  6574.   if System_Mode = Text then  -- change it back
  6575.     Put(TT, Ascii.Esc);
  6576.     Put(TT, "\");
  6577.   end if;
  6578. end Erase_Screen ;
  6579.  
  6580. procedure Erase_Port(Color : in Color_Type) is
  6581. -- Erase the port currently being drawn in.
  6582. begin
  6583.   Erase_Port(Draw_Port, Color_To_Spectrum(Color));
  6584. end Erase_Port ;
  6585.  
  6586. procedure Erase_Port(Color : in Color_Spectrum := 0.0) is
  6587. -- Erase the port currently being drawn in.
  6588. begin
  6589.   Erase_Port(Draw_Port, Color);
  6590. end Erase_Port ;
  6591.  
  6592. procedure Erase_Port(Port: in View_Port; Color : in Color_Type) is
  6593. -- Erase a specified port.
  6594. begin
  6595.   Erase_Port(Port, Color_To_Spectrum(Color));
  6596. end Erase_Port;
  6597.  
  6598. procedure Erase_Port(Port: in View_Port; Color : in Color_Spectrum := 0.0) is
  6599. -- Erase a specified port.
  6600. -- VT240 dependent
  6601.   Y_Min : constant string := integer'image(Adjust_Y_To_Screen(Port.Top));
  6602.   X_Max : constant string := integer'image(Port.Right);
  6603.   New_Intensity : constant Intens_Type := Intensity(Color);
  6604. begin
  6605.   if System_Mode = Text then  -- temporarily change to graphics mode
  6606.     Put(TT, Ascii.Esc); Put(TT, "P1p");
  6607.   end if;
  6608.   if New_Intensity /= Old_Intensity then
  6609.     Put(TT, "W(I(" & New_Intensity & "))");
  6610.     Old_Intensity := New_Intensity;
  6611.   end if;
  6612.   Put(TT, "P["
  6613.           & X_Max
  6614.           & ","
  6615.           & integer'image(Adjust_Y_To_Screen(Port.Bottom))
  6616.           & "]W(S1)V["
  6617.           & X_Max
  6618.           & ","
  6619.           & Y_Min
  6620.           & "]["
  6621.           & integer'image(Port.Left)
  6622.           & ","
  6623.           & Y_Min
  6624.           & "]W(S0)"
  6625.      );
  6626.   if System_Mode = Text then -- change it back
  6627.     Put(TT, Ascii.Esc);
  6628.     Put(TT, "\");
  6629.   end if;
  6630. end Erase_Port;
  6631.  
  6632. procedure Frame_Port is
  6633. -- Draw a frame around the port currently being drawn in.
  6634.   New_Top    : integer := Adjust_Y_To_Screen(Draw_Port.Top);
  6635.   New_Bottom : integer := Adjust_Y_To_Screen(Draw_Port.Bottom);
  6636. begin
  6637.   Draw_Segment(Draw_Port.Left,  New_Top,
  6638.                Draw_Port.Right, New_Top,    Draw_Port.Color);
  6639.   Draw_Segment(Draw_Port.Right, New_Top,
  6640.                Draw_Port.Right, New_Bottom, Draw_Port.Color);
  6641.   Draw_Segment(Draw_Port.Right, New_Bottom,
  6642.                Draw_Port.Left,  New_Bottom, Draw_Port.Color);
  6643.   Draw_Segment(Draw_Port.Left,  New_Bottom,
  6644.                Draw_Port.Left,  New_Top,    Draw_Port.Color);
  6645. end Frame_Port ;
  6646.  
  6647. procedure Move_To(New_X, New_Y: in Coordinate) is
  6648. -- Move the drawing start position to the absolute coordinates (New_X, New_Y).
  6649. begin
  6650.   Draw_Port.X_Current := New_X;
  6651.   Draw_Port.Y_Current := New_Y;
  6652. end Move_To;
  6653.  
  6654. procedure Move_To(New_X, New_Y: in integer) is
  6655. begin
  6656.   Draw_Port.X_Current := float(New_X);
  6657.   Draw_Port.Y_Current := float(New_Y);
  6658. end Move_To;
  6659.  
  6660. procedure Move(Delta_X, Delta_Y: in Coordinate) is
  6661. -- Change the drawing start position by Delta_X and Delta_Y.
  6662. begin
  6663.   Move_To( Draw_Port.X_Current + Delta_X,
  6664.            Draw_Port.Y_Current + Delta_Y );
  6665. end Move;
  6666.  
  6667. procedure Move(Delta_X, Delta_Y: in integer) is
  6668. begin
  6669.   Move_To( Draw_Port.X_Current + float(Delta_X),
  6670.            Draw_Port.Y_Current + float(Delta_Y));
  6671. end Move;
  6672.  
  6673. procedure Clip(X1, Y1, X2, Y2: in out Coordinate; In_View: in out boolean) is
  6674. -- Given an imaginary line segment between the coordinates (X1,Y1) and
  6675. -- (X2, Y2), insure that they are within the current View_Port.
  6676. -- In_View is returned false iff the line segment lies completely outside of
  6677. -- the View_Port.
  6678. -- The algorithm is taken from Newman and Sproull, Principles of Interactive
  6679. -- Computer Graphics pp. 66-67.
  6680. type Edge is (Left, Bottom, Right, Top);
  6681. type Edge_Set is array(Left..Top) of boolean;
  6682.   yy : Edge;
  6683.   C, C1, C2 : Edge_Set;
  6684.   X, Y : Coordinate;
  6685.   None : constant Edge_Set := Edge_Set'(others => false);
  6686.   Off_Screen_Completely : exception;
  6687.  
  6688.   procedure Code(X, Y: in Coordinate; C: out Edge_Set) is
  6689.   begin
  6690.     C := None;
  6691.     if Less_Than(X, Draw_Port.WX_Min) then
  6692.       C(Left) := true;
  6693.     elsif Greater_Than(X, Draw_Port.WX_Max) then
  6694.       C(Right) := true;
  6695.     end if;
  6696.     if Less_Than(Y, Draw_Port.WY_Min) then
  6697.       C(Bottom) := true;
  6698.     elsif Greater_Than(Y, Draw_Port.WY_Max) then
  6699.       C(Top) := true;
  6700.     end if;
  6701.   end Code;
  6702.  
  6703.   function C1_and_C2_ne_None return boolean is
  6704.   -- make up for compiler bug.
  6705.     Result : boolean := false;
  6706.     I      : Edge;
  6707.   begin
  6708.     I := Left;
  6709.     loop
  6710.       if C1(I) and C2(I) then
  6711.         Result := true;
  6712.         exit;
  6713.       end if;
  6714.       exit when I = Top;
  6715.       I := Edge'Succ(I);
  6716.     end loop;
  6717.     return Result;
  6718.   end C1_and_C2_ne_None;
  6719.  
  6720. begin  -- Clip
  6721.   Code(X1, Y1, C1);
  6722.   Code(X2, Y2, C2);
  6723.   while (C1 /= None) or (C2 /= None) loop
  6724.     if C1_and_C2_ne_None then
  6725.       raise Off_Screen_Completely;
  6726.     end if;
  6727.     C := C1;
  6728.     if C = None then
  6729.       C := C2;
  6730.     end if;
  6731.     if C(Left) then       -- Crosses left   edge
  6732.       Y := Y1 + (Y2 - Y1) * (Draw_Port.WX_Min - X1) / (X2 - X1);
  6733.       X := Draw_Port.WX_Min;
  6734.     elsif C(Bottom) then  -- Crosses bottom edge
  6735.       X := X1 + (X2 - X1) * (Draw_Port.WY_Min - Y1) / (Y2 - Y1);
  6736.       Y := Draw_Port.WY_Min;
  6737.     elsif C(Right) then   -- Crosses right  edge
  6738.       Y := Y1 + (Y2 - Y1) * (Draw_Port.WX_Max - X1) / (X2 - X1);
  6739.       X := Draw_Port.WX_Max;
  6740.     elsif C(Top) then     -- Crosses top    edge
  6741.       X := X1 + (X2 - X1) * (Draw_Port.WY_Max - Y1) / (Y2 - Y1);
  6742.       Y := Draw_Port.WY_Max;
  6743.     end if;
  6744.     if C = C1 then
  6745.       X1 := X;
  6746.       Y1 := Y;
  6747.       Code(X, Y, C1);
  6748.     else
  6749.       X2 := X;
  6750.       Y2 := Y;
  6751.       Code(X, Y, C2);
  6752.     end if;
  6753.   end loop;
  6754.   In_View := true;
  6755. exception
  6756.   when Off_Screen_Completely => In_View := false;
  6757. end Clip;
  6758.  
  6759. procedure Line_To(New_X, New_Y: in Coordinate) is
  6760. -- Draw a line from the drawing start position to the absolute coordinates
  6761. -- (New_X, New_Y).
  6762.   SX, SY, EX, EY : Coordinate;
  6763.   Drawable : boolean;
  6764. begin
  6765.   SX := Draw_Port.X_Current;
  6766.   SY := Draw_Port.Y_Current;
  6767.   EX := New_X;
  6768.   EY := New_Y;
  6769.   Clip(SX, SY, EX, EY, Drawable);
  6770.   if Drawable then
  6771.     Draw_Line(SX, SY, EX, EY, Draw_Port.Color);
  6772.   end if;
  6773.   Draw_Port.X_Current := New_X;
  6774.   Draw_Port.Y_Current := New_Y;
  6775. end Line_To;
  6776.  
  6777. procedure Line_To(New_X, New_Y: in integer) is
  6778. begin
  6779.   Line_To(float(New_X), float(New_Y));
  6780. end Line_To;
  6781.  
  6782. procedure Line(Delta_X, Delta_Y: in Coordinate) is
  6783. -- Draw a line from the drawing start position to the point Delta_X and
  6784. -- Delta_Y away.
  6785. begin
  6786.   Line_To( Draw_Port.X_Current + Delta_X,
  6787.            Draw_Port.Y_Current + Delta_Y );
  6788. end Line;
  6789.  
  6790. procedure Line(Delta_X, Delta_Y: in integer) is
  6791. begin
  6792.   Line_To( Draw_Port.X_Current + float(Delta_X),
  6793.            Draw_Port.Y_Current + float(Delta_Y));
  6794. end Line;
  6795.  
  6796. procedure Set_Color(Color_Code: in Color_Spectrum) is
  6797. -- Change the drawing color to Color_Code returning the previous color.
  6798. -- The Color_Spectrum is defined to range from 0.0 (black) to 1.0 (white).
  6799. -- Any color code outside that range will cause Illegal_Color exception to 
  6800. -- be raised.
  6801. begin
  6802.   if Color_Code < 0.0 or Color_Code > 1.0 then
  6803.     raise Illegal_Color;
  6804.   else
  6805.     Draw_Port.Color := Color_Code;
  6806.   end if;
  6807. end Set_Color;
  6808.  
  6809. function Set_Color(Color_Code: in Color_Spectrum) return Color_Spectrum is
  6810.   Old_Color_Code : Color_Spectrum := Draw_Port.Color;
  6811. begin
  6812.   Set_Color(Color_Code);
  6813.   return Old_Color_Code;
  6814. end Set_Color;
  6815.  
  6816. procedure Set_Color(Color: in Color_Type) is
  6817. begin
  6818.   Set_Color(Color_To_Spectrum(Color));
  6819. end Set_Color;
  6820.  
  6821. function Set_Color(Color: in Color_Type) return Color_Type is
  6822.   Old_Color : Color_Type := Spectrum_To_Color(Draw_Port.Color);
  6823. begin
  6824.   Set_Color(Color_To_Spectrum(Color));
  6825.   return Old_Color;
  6826. end Set_Color;
  6827.  
  6828. procedure Where_Am_I(Current_X, Current_Y: out Coordinate) is
  6829. begin
  6830.   Current_X := Draw_Port.X_Current;
  6831.   Current_Y := Draw_Port.Y_Current;
  6832. end Where_Am_I;
  6833.  
  6834. procedure Set_Mode(Mode: in Terminal_Mode) is
  6835. -- VT240 dependent
  6836. begin
  6837.   if Mode /= System_Mode then
  6838.     if Mode = Graphics then
  6839.       Put(TT, Ascii.Esc);
  6840.       Put(TT, "Pp");
  6841.     else
  6842.       Put(TT, Ascii.Esc);
  6843.       Put(TT, "\");
  6844.     end if;
  6845.   end if;
  6846.   System_Mode := Mode;
  6847. end Set_Mode;
  6848.  
  6849. procedure Print_Screen(File_Name : String) is
  6850. -- Put the screen to a file for output to a graphic printer.
  6851. -- This is not implemented for this device.
  6852. begin
  6853.   null;
  6854. end Print_Screen;
  6855.  
  6856. function What_Port return View_Port is
  6857. begin
  6858.   return Draw_Port;
  6859. end What_Port;
  6860.  
  6861. begin  -- Graphic initialization
  6862.   -- VT240 dependent
  6863.     -- Allocate VT240 terminal
  6864.     -- Reset terminal to defaults
  6865.     -- Enter regis mode
  6866.     -- Set color map to Dark, Blue, Red, Green
  6867.     -- Set screen background to Dark
  6868.     -- Turn off graphic cursor
  6869.     -- Erase screen
  6870.     -- Exit regis mode
  6871.   
  6872.   begin
  6873.     Open(TT, Out_File, "TD$VT241:");
  6874.   exception
  6875.     when use_error =>
  6876.       Put("Graphic output going to GRAPH.LIS");
  6877.       Create(TT, Out_File, "GRAPH.LIS");
  6878.   end;
  6879.   Put(TT, Ascii.Esc);
  6880.   Put(TT, "!p");
  6881.   Put(TT, Ascii.Esc);
  6882.   Put(TT, "Pp");
  6883.   Put(TT, "S(M0(L0)1(L33)2(L67)3(L100),I(L0),C0,E)");
  6884.   Put(TT, Ascii.Esc); Put(TT, "\");
  6885. end Graphic;
  6886. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6887. --grvt241.txt
  6888. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6889. with text_io; use text_io;
  6890. package body Graphic is
  6891. -- This is the VT241 body.
  6892.  
  6893. --Required constants for all versions.
  6894.   Screen_X_Max  : constant Pixel := 799;
  6895.   Screen_Y_Max  : constant Pixel := 479;
  6896.   Y_To_X_Ratio  : constant float := 1.0;
  6897.   Epsilon       : constant float := 1.0E-15; -- for math operations, telesoft ada.
  6898.  
  6899. --Required variables for all versions.
  6900.   X_Text_To_Bit : float         := 10.0;
  6901.   Y_Text_To_Bit : float         := 20.0;
  6902.   Draw_Port     : View_Port     := null;
  6903.   System_Mode   : Terminal_Mode := Text;
  6904.  
  6905. --Required terminal dependendent variables
  6906.   TT : File_Type;
  6907.   Old_Color_Char : Character := '?';
  6908.   Last_X, Last_Y : integer   := integer'first;
  6909.  
  6910. function Less_Than(A, B: Coordinate) return boolean is
  6911. begin
  6912.   if abs(A-B) < Epsilon then
  6913.     return false;      --because that's close enough to being equal
  6914.   else
  6915.     return A < B;
  6916.   end if;
  6917. end Less_Than;
  6918.  
  6919. function Greater_Than(A, B: Coordinate) return boolean is
  6920. begin
  6921.   if abs(A-B) < Epsilon then
  6922.     return false;      --because that's close enough to being equal
  6923.   else
  6924.     return A > B;
  6925.   end if;
  6926. end Greater_Than;
  6927.  
  6928. function Equals(A, B: Coordinate) return boolean is
  6929. begin
  6930.   if abs(A-B) < Epsilon then
  6931.     return true;      --because that's close enough to being equal
  6932.   else
  6933.     return false;
  6934.   end if;
  6935. end Equals;
  6936.  
  6937. function Adjust_Y_To_Screen(Y : in integer) return integer is
  6938. -- Isolate the dependency of a terminal's origin location.  Graphic
  6939. -- assumes (0,0) in lower left corner.  If it is a bad assumption,
  6940. -- it is corrected here.
  6941. begin
  6942.   -- for terminals with (0,0) in upper left corner (VT241)
  6943.   -- use
  6944.      return Screen_Y_Max - Y;
  6945.  
  6946.   -- for terminals with (0,0) in lower left corner (Printronix 300)
  6947.   -- use
  6948.   -- return Y;
  6949. end Adjust_Y_To_Screen;
  6950.  
  6951. procedure Redefine(Port: in out View_Port;
  6952.                    Left, Top, Width, Height: in Coordinate) is
  6953.  
  6954.   procedure Verify(Value, Max: in Pixel) is
  6955.   -- verify Value to be between Min and Max.
  6956.   begin
  6957.     if Value < 0 or Value > Max then
  6958.       raise Value_Off_Screen;
  6959.     end if;
  6960.   end Verify;
  6961.  
  6962. begin  -- Redefine
  6963.   Port.Color  := 1.0;   -- start with white
  6964.   Port.Window_Defined := false;
  6965.   Port.Left   := integer(Left*X_Text_To_Bit);
  6966.   Port.Right  := Port.Left + integer(Width*X_Text_To_Bit) - 1;
  6967.   Port.Top    := Screen_Y_Max -  integer(Top*Y_Text_To_Bit);
  6968.   Port.Bottom := Screen_Y_Max - (integer((Top+Height)*Y_Text_To_Bit)-1);
  6969.   Verify(Port.Left,   Screen_X_Max);
  6970.   Verify(Port.Right,  Screen_X_Max);
  6971.   Verify(Port.Top,    Screen_Y_Max);
  6972.   Verify(Port.Bottom, Screen_Y_Max);
  6973.   Draw_Port := Port;
  6974. end Redefine;
  6975.  
  6976. procedure Redefine(Port: in out View_Port;
  6977.                    Left, Top, Width, Height: in integer) is
  6978. begin
  6979.   Redefine(Port, float(Left), float(Top), float(Width), float(Height));
  6980. end Redefine;
  6981.  
  6982. procedure Create_Port(Port: in out View_Port;
  6983.                       Left, Top, Width, Height: in Coordinate) is
  6984. begin
  6985.   Port := new V_Port;
  6986.   Redefine(Port, Left, Top, Width, Height);
  6987. end Create_Port;
  6988.  
  6989. procedure Create_Port(Port: in out View_Port;
  6990.                       Left, Top, Width, Height: in integer) is
  6991. begin
  6992.   Create_Port(Port, float(Left), float(Top), float(Width), float(Height));
  6993. end Create_Port;
  6994.  
  6995. procedure New_Screen_Size(Columns, Lines : in integer) is
  6996. -- Set X_Text_To_Bit and Y_Text_To_Bit to coorespond to a given screen size.
  6997. -- This routine should only have an affect on terminal with varying text
  6998. -- screens.  If Columns and Lines passed do not match some configuration
  6999. -- available on the terminal, Illegal_Screen_Size is raised.
  7000. -- VT241 dependent
  7001. begin
  7002.   case Columns is
  7003.     when     80 => X_Text_To_Bit := 10.0;
  7004.     when    132 => X_Text_To_Bit :=  6.0;
  7005.     when others => raise Illegal_Screen_Size;
  7006.   end case;
  7007.   if Lines /= 24 then
  7008.     raise Illegal_Screen_Size;
  7009.   end if;
  7010. end New_Screen_Size;
  7011.  
  7012. procedure Window_To_Pixel(Window_X, Window_Y : in Coordinate;
  7013.                           Pixel_X,  Pixel_Y  : in out Pixel) is
  7014. -- Translate a window coordinate to a pixel coordinate through the current
  7015. -- drawing port.  If the current drawing port's window has not been defined,
  7016. -- the Undefined_Window exception is raised.
  7017. begin
  7018.   if Draw_Port.Window_Defined then
  7019.     Pixel_X := integer(Window_X * Draw_Port.X_Scale + Draw_Port.X_Shift);
  7020.     Pixel_Y := Adjust_Y_To_Screen(
  7021.                  integer(Window_Y * Draw_Port.Y_Scale + Draw_Port.Y_Shift) );
  7022.   else
  7023.     raise Undefined_Window;
  7024.   end if;
  7025. end Window_To_Pixel;
  7026.  
  7027. procedure Set_Window(Left, Bottom, Right, Top: in Coordinate) is
  7028. -- Defines the world coordinates to be seen through the current View_Port.
  7029. -- If either the width or Height is zero, Set_Window will define them
  7030. -- such that the aspect ratio is sqaure (cause circles to be round).
  7031. -- If both are zero, the Zero_Area exception is raised.
  7032.   Aspect_Ratio : float;
  7033.   Half_Size    : float;      -- Half the X or Y world size of the view port
  7034.   L, B, R, T   : Coordinate; -- Copies of the input parameters
  7035.  
  7036.   function Min(A, B: Coordinate) return Coordinate is
  7037.   begin
  7038.     if A < B then
  7039.       return A;
  7040.     else
  7041.       return B;
  7042.     end if;
  7043.   end Min;
  7044.  
  7045.   function Max(A, B: Coordinate) return Coordinate is
  7046.   begin
  7047.     if A > B then
  7048.       return A;
  7049.     else
  7050.       return B;
  7051.     end if;
  7052.   end Max;
  7053.  
  7054. begin  -- Set_Window
  7055.   if Equals(Left, Right) and Equals(Bottom, Top) then
  7056.     raise Zero_Area;
  7057.   else
  7058.     L := Left;
  7059.     B := Bottom;
  7060.     R := Right;
  7061.     T := Top;
  7062.     Aspect_Ratio := Y_To_X_Ratio * float(Draw_Port.Right - Draw_Port.Left) /
  7063.                                    float(Draw_Port.Top - Draw_Port.Bottom);
  7064.     -- Check for zero area in one direction.
  7065.     -- If found, insure a "square" area port
  7066.     if Equals(Left, Right) then
  7067.       Half_Size := (Top - Bottom) * Aspect_Ratio / 2.0;
  7068.       R := R + Half_Size;
  7069.       L := L - Half_Size;
  7070.     elsif Equals(Top, Bottom) then
  7071.       Half_Size := ((Right - Left) / Aspect_Ratio) / 2.0;
  7072.       T := T + Half_Size;
  7073.       B := B - Half_Size;
  7074.     end if;
  7075.     Draw_Port.WX_Min  := Min(L,R);
  7076.     Draw_Port.WY_Min  := Min(B,T);
  7077.     Draw_Port.WX_Max  := Max(L,R);
  7078.     Draw_Port.WY_Max  := Max(B,T);
  7079.     Draw_Port.X_Scale := float(Draw_Port.Right  - Draw_Port.Left)
  7080.                          / (R - L);
  7081.     Draw_Port.Y_Scale := float(Draw_Port.Top - Draw_Port.Bottom)
  7082.                          / (T - B);
  7083.     Draw_Port.X_Shift := float(Draw_Port.Left)   - L * Draw_Port.X_Scale;
  7084.     Draw_Port.Y_Shift := float(Draw_Port.Bottom) - B * Draw_Port.Y_Scale;
  7085.     Draw_Port.X_Current := 0.0;
  7086.     Draw_Port.Y_Current := 0.0;
  7087.     Draw_Port.Window_Defined := true;
  7088.   end if;
  7089. end Set_Window;
  7090.  
  7091. procedure Set_Window(Left, Bottom, Right, Top: in integer) is
  7092. begin
  7093.   Set_Window(float(Left), float(Bottom), float(Right), float(Top));
  7094. end Set_Window;
  7095.  
  7096. function Color_To_Spectrum(Color : Color_Type) return Color_Spectrum is
  7097. -- Convert a Color_Type to a Color_Spectrum.
  7098. begin
  7099.   Case Color is
  7100.     when Black  => return 0.0;
  7101.     when Brown  => return 0.1667;
  7102.     when Blue   => return 0.3333;
  7103.     when Green  => return 0.5;
  7104.     when Yellow => return 0.6667;
  7105.     when Red    => return 0.8333;
  7106.     when White  => return 1.0;
  7107.     when others => null;
  7108.   end case;
  7109. end Color_To_Spectrum;
  7110.  
  7111. function Spectrum_To_Color(Spectrum : in Color_Spectrum) return Color_Type is
  7112. -- Convert a Color_Spectrum to a Color_Type
  7113. begin
  7114.   case integer(Spectrum*10.0) is
  7115.     when 0      => return Black;
  7116.     when 1..2   => return Brown;
  7117.     when 3      => return Blue;
  7118.     when 4..5   => return Green;
  7119.     when 6..7   => return Yellow;
  7120.     when 8..9   => return Red;
  7121.     when 10     => return White;
  7122.     when others => null;
  7123.   end case;
  7124. end Spectrum_To_Color;
  7125.  
  7126. function Color_Char(Color : Color_Spectrum) return character is
  7127. -- Return the character that the VT241 expects in order to draw
  7128. -- using Color.
  7129. -- VT241 dependent.
  7130.   Color_String : constant string(1..7) := "DDBGYRW";
  7131.   Color_Index  : integer;
  7132. begin
  7133.   Color_Index := 1 + Color_Type'pos(Spectrum_To_Color(Color));
  7134.   return Color_String(Color_Index);
  7135. end Color_Char;
  7136.  
  7137. procedure Draw_Segment(Sx, Sy, Ex, Ey : in integer;
  7138.                        Color : in Color_Spectrum) is
  7139. -- Draw a line segment from (Sx,Sy) to (Ex,Ey) of Color.
  7140. -- VT241 dependent.
  7141.   New_Color_Char : constant character := Color_Char(Color);
  7142. begin
  7143.   if System_Mode = Text then  -- temporarily change to graphics mode
  7144.     Put(TT, Ascii.Esc); Put(TT, "P1p");
  7145.   end if;
  7146.   if New_Color_Char /= Old_Color_Char then
  7147.     Put(TT, "W(I(");
  7148.     Put(TT, New_Color_Char);
  7149.     Put(TT, "))");
  7150.     Old_Color_Char := New_Color_Char;
  7151.   end if;
  7152.   if Sx /= Last_X  or  Sy /= Last_Y then
  7153.     Put(TT, "P[" & integer'image(Sx) & "," & integer'image(Sy) & "]");
  7154.   end if;
  7155.   Put(TT, "V[" & integer'image(Ex) & "," & integer'image(Ey) & "]");
  7156.   New_Line(TT);
  7157.   Last_X := Ex;
  7158.   Last_Y := Ey;
  7159.   if System_Mode = Text then  -- change it back
  7160.     Put(TT, Ascii.Esc); Put(TT, "\");
  7161.   end if;
  7162. end Draw_Segment;
  7163.  
  7164. procedure Draw_Line(Start_WX, Start_WY, End_WX, End_WY : in Coordinate;
  7165.                     Color : in Color_Spectrum) is
  7166. -- Draws a line segment from (Start_WX, Start_WY) to (End_WX, End_WY).  No
  7167. -- clipping is performed.
  7168.   Start_PX, Start_PY, End_PX, End_PY : Pixel;
  7169. begin
  7170.   Window_To_Pixel(Start_WX, Start_WY, Start_PX, Start_PY);
  7171.   Window_To_Pixel(End_WX, End_WY, End_PX, End_PY);
  7172.   Draw_Segment(Start_PX, Start_Py, End_PX, End_PY, Color);
  7173. end Draw_Line;
  7174.  
  7175. procedure Select_Port(Port: in View_Port) is
  7176. -- Select a different port to draw in.
  7177. begin
  7178.   Draw_Port := Port;
  7179. end Select_Port;
  7180.  
  7181. procedure Erase_Screen is
  7182. -- A quick way to erase all graphics on the screen.
  7183. -- VT241 dependent
  7184. begin
  7185.   -- Side effect is all text is erased as well as graphics.
  7186.   if System_Mode = Text then  -- temporarily change to graphics mode
  7187.     Put(TT, Ascii.Esc); Put(TT, "P1p");
  7188.   end if;
  7189.   Put(TT, "S(E)");
  7190.   if System_Mode = Text then  -- change it back
  7191.     Put(TT, Ascii.Esc);
  7192.     Put(TT, "\");
  7193.   end if;
  7194. end Erase_Screen ;
  7195.  
  7196. procedure Erase_Port(Color : in Color_Type) is
  7197. -- Erase the port currently being drawn in.
  7198. begin
  7199.   Erase_Port(Draw_Port, Color_To_Spectrum(Color));
  7200. end Erase_Port ;
  7201.  
  7202. procedure Erase_Port(Color : in Color_Spectrum := 0.0) is
  7203. -- Erase the port currently being drawn in.
  7204. begin
  7205.   Erase_Port(Draw_Port, Color);
  7206. end Erase_Port ;
  7207.  
  7208. procedure Erase_Port(Port: in View_Port; Color : in Color_Type) is
  7209. -- Erase a specified port.
  7210. begin
  7211.   Erase_Port(Port, Color_To_Spectrum(Color));
  7212. end Erase_Port;
  7213.  
  7214. procedure Erase_Port(Port: in View_Port; Color : in Color_Spectrum := 0.0) is
  7215. -- Erase a specified port.
  7216.   Y_Min : constant string := integer'image(Adjust_Y_To_Screen(Port.Top));
  7217.   X_Max : constant string := integer'image(Port.Right);
  7218.   New_Color_Char : constant character := Color_Char(Color);
  7219. begin
  7220.   -- VT240 dependent
  7221.   if System_Mode = Text then  -- temporarily change to graphics mode
  7222.     Put(TT, Ascii.Esc); Put(TT, "P1p");
  7223.   end if;
  7224.   if New_Color_Char /= Old_Color_Char then
  7225.     Put(TT, "W(I(");
  7226.     Put(TT, New_Color_Char);
  7227.     Put(TT, "))");
  7228.     Old_Color_Char := New_Color_Char;
  7229.   end if;
  7230.   Put(TT, "P["
  7231.           & X_Max
  7232.           & ","
  7233.           & integer'image(Adjust_Y_To_Screen(Port.Bottom))
  7234.           & "]W(S1)V["
  7235.           & X_Max
  7236.           & ","
  7237.           & Y_Min
  7238.           & "]["
  7239.           & integer'image(Port.Left)
  7240.           & ","
  7241.           & Y_Min
  7242.           & "]W(S0)"
  7243.      );
  7244.   if System_Mode = Text then -- change it back
  7245.     Put(TT, Ascii.Esc);
  7246.     Put(TT, "\");
  7247.   end if;
  7248. end Erase_Port;
  7249.  
  7250. procedure Frame_Port is
  7251. -- Draw a frame around the port currently being drawn in.
  7252.   New_Top    : integer := Adjust_Y_To_Screen(Draw_Port.Top);
  7253.   New_Bottom : integer := Adjust_Y_To_Screen(Draw_Port.Bottom);
  7254. begin
  7255.   Draw_Segment(Draw_Port.Left,  New_Top,
  7256.                Draw_Port.Right, New_Top,    Draw_Port.Color);
  7257.   Draw_Segment(Draw_Port.Right, New_Top,
  7258.                Draw_Port.Right, New_Bottom, Draw_Port.Color);
  7259.   Draw_Segment(Draw_Port.Right, New_Bottom,
  7260.                Draw_Port.Left,  New_Bottom, Draw_Port.Color);
  7261.   Draw_Segment(Draw_Port.Left,  New_Bottom,
  7262.                Draw_Port.Left,  New_Top,    Draw_Port.Color);
  7263. end Frame_Port ;
  7264.  
  7265. procedure Move_To(New_X, New_Y: in Coordinate) is
  7266. -- Move the drawing start position to the absolute coordinates (New_X, New_Y).
  7267. begin
  7268.   Draw_Port.X_Current := New_X;
  7269.   Draw_Port.Y_Current := New_Y;
  7270. end Move_To;
  7271.  
  7272. procedure Move_To(New_X, New_Y: in integer) is
  7273. begin
  7274.   Draw_Port.X_Current := float(New_X);
  7275.   Draw_Port.Y_Current := float(New_Y);
  7276. end Move_To;
  7277.  
  7278. procedure Move(Delta_X, Delta_Y: in Coordinate) is
  7279. -- Change the drawing start position by Delta_X and Delta_Y.
  7280. begin
  7281.   Move_To( Draw_Port.X_Current + Delta_X,
  7282.            Draw_Port.Y_Current + Delta_Y );
  7283. end Move;
  7284.  
  7285. procedure Move(Delta_X, Delta_Y: in integer) is
  7286. begin
  7287.   Move_To( Draw_Port.X_Current + float(Delta_X),
  7288.            Draw_Port.Y_Current + float(Delta_Y));
  7289. end Move;
  7290.  
  7291. procedure Clip(X1, Y1, X2, Y2: in out Coordinate; In_View: in out boolean) is
  7292. -- Given an imaginary line segment between the coordinates (X1,Y1) and
  7293. -- (X2, Y2), insure that they are within the current View_Port.
  7294. -- In_View is returned false iff the line segment lies completely outside of
  7295. -- the View_Port.
  7296. -- The algorithm is taken from Newman and Sproull, Principles of Interactive
  7297. -- Computer Graphics pp. 66-67.
  7298. type Edge is (Left, Bottom, Right, Top);
  7299. type Edge_Set is array(Left..Top) of boolean;
  7300.   yy : Edge;
  7301.   C, C1, C2 : Edge_Set;
  7302.   X, Y : Coordinate;
  7303.   None : constant Edge_Set := Edge_Set'(others => false);
  7304.   Off_Screen_Completely : exception;
  7305.  
  7306.   procedure Code(X, Y: in Coordinate; C: out Edge_Set) is
  7307.   begin
  7308.     C := None;
  7309.     if Less_Than(X, Draw_Port.WX_Min) then
  7310.       C(Left) := true;
  7311.     elsif Greater_Than(X, Draw_Port.WX_Max) then
  7312.       C(Right) := true;
  7313.     end if;
  7314.     if Less_Than(Y, Draw_Port.WY_Min) then
  7315.       C(Bottom) := true;
  7316.     elsif Greater_Than(Y, Draw_Port.WY_Max) then
  7317.       C(Top) := true;
  7318.     end if;
  7319.   end Code;
  7320.  
  7321.   function C1_and_C2_ne_None return boolean is
  7322.   -- make up for compiler bug.
  7323.     Result : boolean := false;
  7324.     I      : Edge;
  7325.   begin
  7326.     I := Left;
  7327.     loop
  7328.       if C1(I) and C2(I) then
  7329.         Result := true;
  7330.         exit;
  7331.       end if;
  7332.       exit when I = Top;
  7333.       I := Edge'Succ(I);
  7334.     end loop;
  7335.     return Result;
  7336.   end C1_and_C2_ne_None;
  7337.  
  7338. begin  -- Clip
  7339.   Code(X1, Y1, C1);
  7340.   Code(X2, Y2, C2);
  7341.   while (C1 /= None) or (C2 /= None) loop
  7342.     if C1_and_C2_ne_None then
  7343.       raise Off_Screen_Completely;
  7344.     end if;
  7345.     C := C1;
  7346.     if C = None then
  7347.       C := C2;
  7348.     end if;
  7349.     if C(Left) then       -- Crosses left   edge
  7350.       Y := Y1 + (Y2 - Y1) * (Draw_Port.WX_Min - X1) / (X2 - X1);
  7351.       X := Draw_Port.WX_Min;
  7352.     elsif C(Bottom) then  -- Crosses bottom edge
  7353.       X := X1 + (X2 - X1) * (Draw_Port.WY_Min - Y1) / (Y2 - Y1);
  7354.       Y := Draw_Port.WY_Min;
  7355.     elsif C(Right) then   -- Crosses right  edge
  7356.       Y := Y1 + (Y2 - Y1) * (Draw_Port.WX_Max - X1) / (X2 - X1);
  7357.       X := Draw_Port.WX_Max;
  7358.     elsif C(Top) then     -- Crosses top    edge
  7359.       X := X1 + (X2 - X1) * (Draw_Port.WY_Max - Y1) / (Y2 - Y1);
  7360.       Y := Draw_Port.WY_Max;
  7361.     end if;
  7362.     if C = C1 then
  7363.       X1 := X;
  7364.       Y1 := Y;
  7365.       Code(X, Y, C1);
  7366.     else
  7367.       X2 := X;
  7368.       Y2 := Y;
  7369.       Code(X, Y, C2);
  7370.     end if;
  7371.   end loop;
  7372.   In_View := true;
  7373. exception
  7374.   when Off_Screen_Completely => In_View := false;
  7375. end Clip;
  7376.  
  7377. procedure Line_To(New_X, New_Y: in Coordinate) is
  7378. -- Draw a line from the drawing start position to the absolute coordinates
  7379. -- (New_X, New_Y).
  7380.   SX, SY, EX, EY : Coordinate;
  7381.   Drawable : boolean;
  7382. begin
  7383.   SX := Draw_Port.X_Current;
  7384.   SY := Draw_Port.Y_Current;
  7385.   EX := New_X;
  7386.   EY := New_Y;
  7387.   Clip(SX, SY, EX, EY, Drawable);
  7388.   if Drawable then
  7389.     Draw_Line(SX, SY, EX, EY, Draw_Port.Color);
  7390.   end if;
  7391.   Draw_Port.X_Current := New_X;
  7392.   Draw_Port.Y_Current := New_Y;
  7393. end Line_To;
  7394.  
  7395. procedure Line_To(New_X, New_Y: in integer) is
  7396. begin
  7397.   Line_To(float(New_X), float(New_Y));
  7398. end Line_To;
  7399.  
  7400. procedure Line(Delta_X, Delta_Y: in Coordinate) is
  7401. -- Draw a line from the drawing start position to the point Delta_X and
  7402. -- Delta_Y away.
  7403. begin
  7404.   Line_To( Draw_Port.X_Current + Delta_X,
  7405.            Draw_Port.Y_Current + Delta_Y );
  7406. end Line;
  7407.  
  7408. procedure Line(Delta_X, Delta_Y: in integer) is
  7409. begin
  7410.   Line_To( Draw_Port.X_Current + float(Delta_X),
  7411.            Draw_Port.Y_Current + float(Delta_Y));
  7412. end Line;
  7413.  
  7414. procedure Set_Color(Color_Code: in Color_Spectrum) is
  7415. -- Change the drawing color to Color_Code returning the previous color.
  7416. -- The Color_Spectrum is defined to range from 0.0 (black) to 1.0 (white).
  7417. -- Any color code outside that range will cause Illegal_Color exception to 
  7418. -- be raised.
  7419. begin
  7420.   if Color_Code < 0.0 or Color_Code > 1.0 then
  7421.     raise Illegal_Color;
  7422.   else
  7423.     Draw_Port.Color := Color_Code;
  7424.   end if;
  7425. end Set_Color;
  7426.  
  7427. function Set_Color(Color_Code: in Color_Spectrum) return Color_Spectrum is
  7428.   Old_Color_Code : Color_Spectrum := Draw_Port.Color;
  7429. begin
  7430.   Set_Color(Color_Code);
  7431.   return Old_Color_Code;
  7432. end Set_Color;
  7433.  
  7434. procedure Set_Color(Color: in Color_Type) is
  7435. begin
  7436.   Set_Color(Color_To_Spectrum(Color));
  7437. end Set_Color;
  7438.  
  7439. function Set_Color(Color: in Color_Type) return Color_Type is
  7440.   Old_Color : Color_Type := Spectrum_To_Color(Draw_Port.Color);
  7441. begin
  7442.   Set_Color(Color_To_Spectrum(Color));
  7443.   return Old_Color;
  7444. end Set_Color;
  7445.  
  7446. procedure Where_Am_I(Current_X, Current_Y: out Coordinate) is
  7447. begin
  7448.   Current_X := Draw_Port.X_Current;
  7449.   Current_Y := Draw_Port.Y_Current;
  7450. end Where_Am_I;
  7451.  
  7452. procedure Set_Mode(Mode: in Terminal_Mode) is
  7453. -- VT241 dependent
  7454. begin
  7455.   if Mode /= System_Mode then
  7456.     if Mode = Graphics then
  7457.       Put(TT, Ascii.Esc);
  7458.       Put(TT, "Pp");
  7459.     else
  7460.       Put(TT, Ascii.Esc);
  7461.       Put(TT, "\");
  7462.     end if;
  7463.   end if;
  7464.   System_Mode := Mode;
  7465. end Set_Mode;
  7466.  
  7467. procedure Print_Screen(File_Name : String) is
  7468. -- Put the screen to a file for output to a graphic printer.
  7469. -- This is not implemented for this device.
  7470. begin
  7471.   null;
  7472. end Print_Screen;
  7473.  
  7474. function What_Port return View_Port is
  7475. begin
  7476.   return Draw_Port;
  7477. end What_Port;
  7478.  
  7479. begin  -- Graphic initialization
  7480.   -- VT241 dependent
  7481.     -- Allocate VT241 terminal
  7482.     -- Reset terminal to defaults
  7483.     -- Enter regis mode
  7484.     -- Set color map to Dark, Blue, Red, Green
  7485.     -- Set screen background to Dark
  7486.     -- Turn off graphic cursor
  7487.     -- Erase screen
  7488.     -- Exit regis mode
  7489.   
  7490.   begin
  7491.     Open(TT, Out_File, "TD$VT241:");
  7492.   exception
  7493.     when use_error =>
  7494.       Put("Graphic output going to GRAPH.LIS");
  7495.       Create(TT, Out_File, "GRAPH.LIS");
  7496.   end;
  7497.   Put(TT, Ascii.Esc);
  7498.   Put(TT, "!p");
  7499.   Put(TT, Ascii.Esc);
  7500.   Put(TT, "Pp");
  7501.   Put(TT, "S(M0(D)1(B)2(R)3(G),I(D),C0,E)");
  7502.   Put(TT, Ascii.Esc); Put(TT, "\");
  7503. end Graphic;
  7504. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  7505. --plotmenu.sp
  7506. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  7507.  
  7508. with GRAPHIC;
  7509. package PLOT_MENU is
  7510.  
  7511.   use GRAPHIC;
  7512.  
  7513.   subtype FILENAME  is string ( 1 .. 40 );
  7514.   subtype MAP_TITLE is string ( 1 .. 40 );
  7515.  
  7516.   type KIND_OF_PROJECTION is ( STEREOgraphic, ORTHOgraphic, GNOMONIC, SATELLITE,
  7517.                  LAMBERT,      AZIMUTHAL,    CARTESIAN,  MERCATOR );
  7518.  
  7519.   type PROJECTION_PARAMETERS is
  7520.     record
  7521.       LAT_CENTER      :      float;
  7522.       LON_CENTER      :      float;
  7523.       CLK_ROT_AR_CENT :      float;
  7524.       SAT_ALTITUDE    :      float;
  7525.       VIEW_ALTITUDE   :      float;
  7526.     end record;
  7527.  
  7528.   type GRID_LINE_PARAMETERS is
  7529.     record
  7530.       SHOW_LINES            :      boolean;
  7531.       DEGREES_BTWN_LATS     :      float;
  7532.       DEGREES_BTWN_LONS     :      float;
  7533.       SEGMENT_LENGTH        :      float;
  7534.     end record;
  7535.  
  7536.   type KIND_OF_PROJECTION_LIMIT is ( ALL_EARTH, MIN_MAX_LAT_LON, 
  7537.             MIN_MAX_COORDINATES, ANGULAR_DIST_FROM_PROJECTION_CENTER,
  7538.             LAT_LON_BOUNDARY );
  7539.  
  7540.   type CORRD is 
  7541.     record
  7542.       X      :      float;
  7543.       Y      :      float;
  7544.     end record;
  7545.  
  7546.   type PROJECTION_LIMITS is
  7547.     record
  7548.       MIN_LAT_LON           :  CORRD;
  7549.       MAX_LAT_LON           :  CORRD;
  7550.       NORTH_EAST            :  CORRD;
  7551.       SOUTH_WEST            :  CORRD;
  7552.       ANGLE_UP              :  float;
  7553.       ANGLE_DOWN            :  float;
  7554.       ANGLE_RIGHT           :  float;
  7555.       ANGLE_LEFT            :  float;
  7556.       POINT_UP              :  CORRD;
  7557.       POINT_DOWN            :  CORRD;
  7558.       POINT_RIGHT           :  CORRD;
  7559.       POINT_LEFT            :  CORRD;
  7560.     end record;
  7561.  
  7562.   type COLOR_SELECTION is
  7563.     record
  7564.       BACKGROUND            :      COLOR_TYPE;
  7565.       DEFAULT               :      COLOR_TYPE;
  7566.       MAP_OUTLINE           :      COLOR_TYPE;
  7567.       GRID_LINES            :      COLOR_TYPE;
  7568.       HORIZON               :      COLOR_TYPE;
  7569.     end record;
  7570.  
  7571.   type SPECIAL_DISPLAYS is
  7572.     record
  7573.       BEAM_DATA          :      FILENAME  ;
  7574.       BEAM_COLOR         :      COLOR_TYPE;
  7575.       BEAM_LAST          :      integer;
  7576.       SWATH_DATA         :      FILENAME  ;
  7577.       SWATH_COLOR        :      COLOR_TYPE;
  7578.       SWATH_LAST         :      integer;
  7579.       POINTS_DATA        :      FILENAME  ;
  7580.       POINTS_COLOR       :      COLOR_TYPE;
  7581.       POINTS_LAST        :      integer;
  7582.     end record;
  7583.  
  7584.   type DIAGNOSTICS is
  7585.     record
  7586.       WARNING            :      boolean;
  7587.       ERROR              :      boolean;
  7588.       FATAL              :      boolean;
  7589.     end record;
  7590.  
  7591.   type PLOT_CHARACTERISTICS is
  7592.     record
  7593.       AXIS_LENGTH      :      CORRD;
  7594.       ORIGIN           :      CORRD;
  7595.     end record;
  7596.  
  7597.   TYPE_OF_PROJECTION            :      KIND_OF_PROJECTION;
  7598.   TYPE_OF_PROJECTION_LIMIT      :      KIND_OF_PROJECTION_LIMIT;
  7599.  
  7600.   Current_TITLE                 :      MAP_TITLE;
  7601.   CURRENT_GRID_LINE_PARAMETERS  :      GRID_LINE_PARAMETERS;
  7602.   CURRENT_COLOR_SELECTION       :      COLOR_SELECTION;
  7603.   CURRENT_SPECIAL_DISPLAYS      :      SPECIAL_DISPLAYS;
  7604.  
  7605.   CURRENT_PROJECTION_PARAMETERS :      PROJECTION_PARAMETERS;
  7606.   CURRENT_PROJECTION_LIMITS     :      PROJECTION_LIMITS;
  7607.  
  7608.   CURRENT_PLOT_CHAR             :      PLOT_CHARACTERISTICS;
  7609.  
  7610. --  CLIPPING                      :      boolean;
  7611.   PLOT_LAND                     :      boolean;
  7612.   
  7613.   CURRENT_DIAGNOSTICS           :      DIAGNOSTICS;
  7614.  
  7615.   function  SHOW_GRID                     return boolean;
  7616.   function  SHOW_BEAM                     return boolean;
  7617.   function  SHOW_SWATH                    return boolean;
  7618.  
  7619.   procedure DRAW_ERROR_PORT ( TEXT1 : in string; TEXT : in string );
  7620.  
  7621.   procedure OPEN_MENU_FILE   ( FILE : in string ); -- use for OPENF command.
  7622.   procedure CLOSE_MENU_FILE; -- use for OPENF & SAVE commands.
  7623.  
  7624.   procedure READ_SESSION_DEFAULTS;
  7625.  
  7626. end PLOT_MENU;
  7627. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  7628. --plotmenu.txt
  7629. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  7630. with text_io;
  7631. package body PLOT_MENU is
  7632.  
  7633.   use TEXT_IO;
  7634.   package FLT_IO is new FLOAT_IO ( float );
  7635.   use FLT_IO;
  7636.  
  7637.   CURRENT_FILE      :      FILE_TYPE;
  7638.  
  7639.   HOLD_STRING       :      string ( 1 .. 40 ) := ( 1 .. 40 => ' ' );
  7640.   LAST              :      integer := 0;
  7641.  
  7642.   function SHOW_GRID                     return boolean is
  7643.   begin
  7644.     return CURRENT_GRID_LINE_parameters.SHOW_LINES;
  7645.   end SHOW_GRID;
  7646.  
  7647.   function SHOW_BEAM                     return boolean is
  7648.     TEMP      :      boolean      := false;
  7649.   begin
  7650.     if current_special_displays.BEAM_LAST /= 0 then
  7651.       TEMP := true;
  7652.     end if;
  7653.     return TEMP;
  7654.   end SHOW_BEAM;
  7655.  
  7656.   function SHOW_SWATH                    return boolean is
  7657.     TEMP      :      boolean      := false;
  7658.   begin
  7659.     if current_special_displays.SWATH_LAST /= 0 then
  7660.       TEMP := true;
  7661.     end if;
  7662.     return TEMP;
  7663.   end SHOW_SWATH;
  7664.  
  7665.   procedure DRAW_ERROR_PORT ( TEXT1: IN STRING; TEXT : IN STRING ) IS
  7666.   BEGIN
  7667.     NULL;
  7668.   END;
  7669.  
  7670.   procedure OPEN_MENU_FILE   ( FILE : in string ) is -- use for OPENF command.
  7671.   begin
  7672.     OPEN ( CURRENT_FILE, IN_FILE, FILE ( FILE'first .. FILE'last ) );
  7673.   end OPEN_MENU_FILE;
  7674.  
  7675.   procedure CLOSE_MENU_FILE is -- use for OPENF & SAVE commands.
  7676.   begin
  7677.     CLOSE ( CURRENT_FILE );
  7678.   end CLOSE_MENU_FILE;
  7679.  
  7680.   procedure READ             ( ITEM : in out float  ) is
  7681.   begin
  7682.     GET ( CURRENT_FILE, ITEM );
  7683.     SKIP_LINE ( CURRENT_FILE );
  7684.   end READ;
  7685.  
  7686.   procedure READ             ( ITEM : in out string; LAST : in out integer ) is
  7687.   begin
  7688.     GET_LINE ( CURRENT_FILE, ITEM, LAST );
  7689.   end READ;
  7690.  
  7691.   procedure READ_DISPLAY_DEFAULTS is
  7692.   begin
  7693.     READ ( current_TITLE, LAST );
  7694.     READ ( HOLD_STRING, LAST );
  7695.     TYPE_OF_PROJECTION := KIND_OF_PROJECTION'value 
  7696.                                     ( HOLD_STRING ( 1 .. LAST ) );
  7697.     READ ( CURRENT_PROJECTION_PARAMETERS.LAT_CENTER );
  7698.     READ ( CURRENT_PROJECTION_PARAMETERS.LON_CENTER );
  7699.     READ ( CURRENT_PROJECTION_PARAMETERS.CLK_ROT_AR_CENT );
  7700.     READ ( CURRENT_PROJECTION_PARAMETERS.SAT_ALTITUDE );
  7701.     READ ( CURRENT_PROJECTION_PARAMETERS.VIEW_ALTITUDE );
  7702.     READ ( HOLD_STRING, LAST );
  7703.     TYPE_OF_PROJECTION_LIMIT := KIND_OF_PROJECTION_LIMIT'value 
  7704.                                     ( HOLD_STRING ( 1 .. LAST ) );
  7705.     READ ( CURRENT_PROJECTION_LIMITS.MIN_LAT_LON.X );
  7706.     READ ( CURRENT_PROJECTION_LIMITS.MIN_LAT_LON.Y );
  7707.     READ ( CURRENT_PROJECTION_LIMITS.MAX_LAT_LON.X );
  7708.     READ ( CURRENT_PROJECTION_LIMITS.MAX_LAT_LON.Y );
  7709.     READ ( CURRENT_PROJECTION_LIMITS.NORTH_EAST.X );
  7710.     READ ( CURRENT_PROJECTION_LIMITS.NORTH_EAST.Y );
  7711.     READ ( CURRENT_PROJECTION_LIMITS.SOUTH_WEST.X );
  7712.     READ ( CURRENT_PROJECTION_LIMITS.SOUTH_WEST.Y );
  7713.     READ ( CURRENT_PROJECTION_LIMITS.ANGLE_UP );
  7714.     READ ( CURRENT_PROJECTION_LIMITS.ANGLE_DOWN );
  7715.     READ ( CURRENT_PROJECTION_LIMITS.ANGLE_RIGHT );
  7716.     READ ( CURRENT_PROJECTION_LIMITS.ANGLE_LEFT );
  7717.     READ ( CURRENT_PROJECTION_LIMITS.POINT_UP.X );
  7718.     READ ( CURRENT_PROJECTION_LIMITS.POINT_UP.Y );
  7719.     READ ( CURRENT_PROJECTION_LIMITS.POINT_DOWN.X );
  7720.     READ ( CURRENT_PROJECTION_LIMITS.POINT_DOWN.Y );
  7721.     READ ( CURRENT_PROJECTION_LIMITS.POINT_RIGHT.X );
  7722.     READ ( CURRENT_PROJECTION_LIMITS.POINT_RIGHT.Y );
  7723.     READ ( CURRENT_PROJECTION_LIMITS.POINT_LEFT.X );
  7724.     READ ( CURRENT_PROJECTION_LIMITS.POINT_LEFT.Y );
  7725.     READ ( HOLD_STRING, LAST );
  7726.     CURRENT_COLOR_SELECTION.BACKGROUND := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  7727.     READ ( HOLD_STRING, LAST );
  7728.     CURRENT_COLOR_SELECTION.DEFAULT := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  7729.     READ ( HOLD_STRING, LAST );
  7730.     CURRENT_COLOR_SELECTION.MAP_OUTLINE := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  7731.     READ ( HOLD_STRING, LAST );
  7732.     CURRENT_COLOR_SELECTION.GRID_LINES := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  7733.     READ ( HOLD_STRING, LAST );
  7734.     CURRENT_COLOR_SELECTION.HORIZON := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  7735.     READ ( HOLD_STRING, LAST );
  7736.     CURRENT_GRID_LINE_PARAMETERS.SHOW_LINES := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  7737.     READ ( CURRENT_GRID_LINE_PARAMETERS.DEGREES_BTWN_LATS );
  7738.     READ ( CURRENT_GRID_LINE_PARAMETERS.DEGREES_BTWN_LONS );
  7739.     READ ( CURRENT_GRID_LINE_PARAMETERS.SEGMENT_LENGTH );
  7740. --    READ ( HOLD_STRING, LAST );
  7741. --    CLIPPING := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  7742.     READ ( HOLD_STRING, LAST );
  7743.     PLOT_LAND := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  7744.   exception
  7745.     when others =>
  7746.       raise CONSTRAINT_ERROR;
  7747.   end READ_DISPLAY_DEFAULTS;
  7748.  
  7749.   procedure READ_SESSION_DEFAULTS is
  7750.   begin
  7751.     READ_DISPLAY_DEFAULTS;
  7752.     READ ( CURRENT_SPECIAL_DISPLAYS.BEAM_DATA, LAST );
  7753.     READ ( HOLD_STRING, LAST );
  7754.     CURRENT_SPECIAL_DISPLAYS.BEAM_COLOR := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  7755.     READ ( HOLD_STRING, LAST );
  7756.     CURRENT_SPECIAL_DISPLAYS.BEAM_LAST := integer'value ( HOLD_STRING ( 1 .. LAST ) );
  7757.     READ ( CURRENT_SPECIAL_DISPLAYS.SWATH_DATA, LAST );
  7758.     READ ( HOLD_STRING, LAST );
  7759.     CURRENT_SPECIAL_DISPLAYS.SWATH_COLOR := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  7760.     READ ( HOLD_STRING, LAST );
  7761.     CURRENT_SPECIAL_DISPLAYS.SWATH_LAST := integer'value ( HOLD_STRING ( 1 .. LAST ) );
  7762.     READ ( CURRENT_SPECIAL_DISPLAYS.POINTS_DATA, LAST );
  7763.     READ ( HOLD_STRING, LAST );
  7764.     CURRENT_SPECIAL_DISPLAYS.POINTS_COLOR := COLOR_TYPE'value ( HOLD_STRING ( 1 .. LAST ) );
  7765.     READ ( HOLD_STRING, LAST );
  7766.     CURRENT_SPECIAL_DISPLAYS.POINTS_LAST := integer'value ( HOLD_STRING ( 1 .. LAST ) );
  7767.     READ ( HOLD_STRING, LAST );
  7768.     CURRENT_DIAGNOSTICS.WARNING := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  7769.     READ ( HOLD_STRING, LAST );
  7770.     CURRENT_DIAGNOSTICS.ERROR := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  7771.     READ ( HOLD_STRING, LAST );
  7772.     CURRENT_DIAGNOSTICS.FATAL := boolean'value ( HOLD_STRING ( 1 .. LAST ) );
  7773.     READ ( current_PLOT_CHAR.AXIS_LENGTH.X );
  7774.     READ ( current_PLOT_CHAR.AXIS_LENGTH.Y );
  7775.     READ ( current_PLOT_CHAR.ORIGIN.X );
  7776.     READ ( current_PLOT_CHAR.ORIGIN.Y ); 
  7777.   exception
  7778.     when others =>
  7779.       raise CONSTRAINT_ERROR;
  7780.   end READ_SESSION_DEFAULTS;
  7781.  
  7782. begin
  7783.   null;
  7784. end PLOT_MENU;
  7785. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  7786. --plot.txt
  7787. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  7788. with Text_Io, Core_Functions, Trig_Lib, Numeric_Primitives,
  7789.      Plot_Menu, World_Data_Files;
  7790. use  Text_Io, Core_Functions, Trig_Lib, Numeric_Primitives,
  7791.      Plot_Menu, World_Data_Files, Graphic;
  7792. procedure Plot is
  7793.   Map    : View_Port;
  7794.   Namer  : string ( 1 .. 40 ) := ( 1 .. 40 => ' ' );
  7795.   Laster : integer := 0;
  7796.  
  7797. procedure Draw_Map is
  7798. -- Draw the map defined by the World_Menus package.
  7799. type Beam_Or_Symbol is (Map_Data, Beam_Data, Symbol_Data);
  7800.   Eps     : constant float := 1.0E-7;  -- Small number used to avoid divide by zero errors.
  7801.   Way_Out : constant float := 1.0E+8;  -- A location always off the screen.
  7802.   Radians_Per_Degree : constant float := 0.0174532925;
  7803.   Degrees_Per_Radian : constant float := 57.295779510;
  7804.   Max_Points  : constant := 400;
  7805.   type Float_Array is array (1..Max_Points) of float;
  7806.   Map_Color   : constant Color_Selection 
  7807.                            := Plot_Menu.Current_Color_Selection;
  7808.   Limit_Type  : constant Kind_Of_Projection_Limit
  7809.                            := Type_Of_Projection_Limit;
  7810.   Projection  : Kind_Of_Projection := Type_Of_Projection;
  7811.   Proj_Params : Projection_Parameters;
  7812.   Specials    : constant Special_Displays := Current_Special_Displays;
  7813.   Max_Line    : float;  -- The longest allowable line on the screen.
  7814.   Phio        : float;  -- The longitude center of the projection.
  7815.   Symbol      : integer;-- The symbol to be used  1 --> Square
  7816.                         --                        2 --> Plus
  7817.                         --                        3 --> Diamond
  7818.                         --                        4 --> Triangle
  7819.   Symbol_Size : float;  -- The size of the symbol to be drawn is
  7820.   Symbol_Scale: constant float := 100.0; -- <window width> / Symbol_Scale.
  7821.   Lon_Pic_Min,
  7822.   Lon_Pic_Max,          -- The min's and max's of the viewport
  7823.   Lat_Pic_Min,          -- used to avoid plotting points that cannot
  7824.   Lat_Pic_Max : float;  -- possibly be visible.
  7825.   SinO,
  7826.   CosO,                 -- Sin and Cos of the center of the projection
  7827.   SinR,
  7828.   CosR : float;         -- Sin and Cos of the rotation
  7829.   Umin,
  7830.   Umax,                 -- The basis for determining the windowing
  7831.   Vmin,                 -- of the Viewport.
  7832.   Vmax : float;
  7833.   Caught_Error : exception;
  7834.  
  7835.   function Sat_Scale(Alt, Ref_Alt : float) return float is
  7836.   -- Finds scale for satellite view.
  7837.     Earth_Radius : constant float := 3443.9336;
  7838.     F, H, Alfa, Beta : float;
  7839.   begin
  7840.     if Alt <= 0.0 then
  7841.       Put_Line("Invalid Satellite Altitude.  Plot aborted.");
  7842.       raise Caught_Error;
  7843.     elsif Ref_Alt <= 0.0 then
  7844.       Put_Line("Invalid Satellite Reference Altitude.  Plot aborted.");
  7845.       raise Caught_Error;
  7846.     end if;
  7847.     F    := Ref_Alt / Earth_Radius;
  7848.     H    := Alt     / Earth_Radius;
  7849.     Beta := ASin(1.0 / (1.0 + H));
  7850.     Alfa := ASin(1.0 / (1.0 + F));
  7851.     F    := Tan(Beta) / Tan(Alfa);
  7852.     return F / (H * Beta);
  7853.   end Sat_Scale;
  7854.  
  7855.   procedure Project(Lat, Lon : in float; U, V : out float) is
  7856.   -- Sets up the calls to the various projection algorithms.
  7857.   -- The point (Lat, Lon) is input in degrees and is transformed
  7858.   -- to (U, V) in the mapping coordinates according to the kind
  7859.   -- of projection.
  7860.     R, H, SinA, CosA, SinB, CosB, SinPH, CosPH, SinLat, CosLat : float;
  7861.     Del_Lon : float;
  7862.  
  7863.     function Calc_Del_Lon(Lon : float) return float is
  7864.     -- Offsets Lon by the center of the projection adjusting for wraparound.
  7865.       Del_Lon : float;
  7866.     begin
  7867.       Del_Lon := Lon - Phio;
  7868.       if Del_Lon >= 180.0 then
  7869.         Del_Lon := Del_Lon - 360.0;
  7870.       elsif Del_Lon < -180.0 then
  7871.         Del_Lon := Del_Lon + 360.0;
  7872.       end if;
  7873.       return Del_Lon;
  7874.     end Calc_Del_Lon;
  7875.  
  7876.     procedure Do_Trig_Calculations is
  7877.     begin
  7878.       SinPH  := Sin(Del_Lon * Radians_Per_Degree);
  7879.       CosPH  := Cos(Del_Lon * Radians_Per_Degree);
  7880.       SinLat := Sin(    Lat * Radians_Per_Degree);
  7881.       CosLat := Cos(    Lat * Radians_Per_Degree);
  7882.       CosA   := SinLat*SinO + CosLat*CosO*CosPH;
  7883.       if abs(CosA) > 1.0 then
  7884.         CosA := Sign(1.0, CosA);
  7885.       end if;
  7886.       SinA := Sqrt( 1.0 + Eps - CosA*CosA);
  7887.       SinB := CosLat * SinPH / SinA;
  7888.       CosB := (SinLat*CosO - CosLat*SinO*CosPH) / SinA;
  7889.     end Do_Trig_Calculations;
  7890.  
  7891.    procedure Cylin(Lat, Lon : in float; U, V : out float) is
  7892.     -- This is a cylindrcal projection routine.
  7893.     -- Point (Lat, Lon) is transformed to mapping coordinates (U, V).
  7894.       Out_Of_Range : exception;
  7895.     begin
  7896.       Del_Lon := Calc_Del_Lon(Lon);
  7897.       if Proj_Params.Lat_Center = 0.0 then
  7898.         Case Projection is
  7899.           when Cartesian => U := Del_Lon;
  7900.                             V := Lat;
  7901.           when Mercator  => U := Del_Lon * Radians_Per_Degree;
  7902.                             V := Log( Tan(0.00872664*(Lat+90.0001)) );
  7903.           when others    => null;
  7904.         end case;
  7905.       else
  7906.         Do_Trig_Calculations;
  7907.         Case Projection is
  7908.           when Cartesian =>
  7909.             if abs(1.0 - CosA*CosA) < 1.0E-4 then
  7910.               raise Out_Of_Range;
  7911.             end if;
  7912.             U := ATan2(SinB*CosR + CosB*SinR, SinB*SinR - CosB*CosR)
  7913.                  * Degrees_Per_Radian;
  7914.             V := 90.0 - ACos(CosA)*Degrees_Per_Radian;
  7915.           when Mercator  =>
  7916.             if abs(1.0 - CosA*CosA) < 2.0E-6 then
  7917.               raise Out_Of_Range;
  7918.             end if;
  7919.             U := ATan2(SinB*CosR + CosB*SinR, SinB*SinR - CosB*CosR);
  7920.             V := Log( (1.0+CosA) / SinA);
  7921.           when others    => null;
  7922.         end case;
  7923.       end if;
  7924.     exception
  7925.       when Out_Of_Range =>
  7926.         U := Way_Out;
  7927.         V := Way_Out;
  7928.     end Cylin;
  7929.  
  7930.     procedure Azim(Lat, Lon : in float; U, V : out float) is
  7931.     -- This is an Azimuthal projection routine.
  7932.     -- Point (Lat, Lon) is transformed to mapping coordinates (U, V).
  7933.       R, H : float;
  7934.       Out_Of_Range : exception;
  7935.     begin  -- Azim
  7936.       Del_Lon := Calc_Del_Lon(Lon);
  7937.       Do_Trig_Calculations;
  7938.       case Projection is
  7939.         when Stereographic =>
  7940.           R := (1.0 - CosA) / SinA;
  7941.         when Gnomonic     => null;
  7942.           if CosA <= 0.0 then
  7943.             raise Out_Of_Range;
  7944.           end if;
  7945.           R := SinA / CosA;
  7946.         when Lambert      =>
  7947.           if abs(CosA+1.0) < 1.0E-6 then
  7948.             raise Out_Of_Range;
  7949.           end if;
  7950.           R := (1.0 + CosA) / SinA;
  7951.           R := 2.0 / (Sqrt(1.0 + R*R));
  7952.         when Orthographic =>
  7953.           if CosA <= 0.0 then
  7954.             raise Out_Of_Range;
  7955.           end if;
  7956.           R := SinA;
  7957.         when Satellite    =>
  7958.           H := Proj_Params.Sat_Altitude / 3444.0;
  7959.           if (CosA - 1.0/(H+1.0)) <= 0.0 then
  7960.             raise Out_Of_Range;
  7961.           end if;
  7962.           R := Sat_Scale(Proj_Params.Sat_Altitude, Proj_Params.View_Altitude)
  7963.                  * H * ATan( SinA / (H+1.0-CosA));
  7964.         when Azimuthal    => null;
  7965.           if abs(CosA+1.0) < 1.0E-6 then
  7966.             raise Out_Of_Range;
  7967.           end if;
  7968.           R := ACos(CosA);
  7969.         when others       => null;
  7970.       end case;
  7971.       U := R * (SinB*CosR + CosB*SinR);
  7972.       V := R * (CosB*CosR - SinB*SinR);
  7973.     exception
  7974.       when Out_Of_Range =>
  7975.         U := Way_Out;
  7976.         V := Way_Out;
  7977.     end Azim;
  7978.  
  7979.   begin  -- Project
  7980.     case Projection is
  7981.       when Cartesian  |
  7982.            Mercator   => Cylin(Lat, Lon, U, V);
  7983.       when others     => Azim(Lat, Lon, U, V);
  7984.     end case;
  7985.   end Project;
  7986.  
  7987.   procedure Initialize_Plot is
  7988.   -- Sets Umin, Umax, Vmin, and Vmax.  In other words, it determines
  7989.   -- the minimums and maximums of the viewing of the projection.
  7990.   -- These four variables are what determine the "zooming" characteristics.
  7991.     Limits : constant Projection_Limits
  7992.                := Plot_Menu.Current_Projection_Limits;
  7993.     Phia   : float;      -- the latitude center of the projection.
  7994.     SinO1, CosO1 : float;
  7995.  
  7996.     procedure Do_All_Earth is
  7997.     -- Set limits to see as much of the earth is possible for this projection.
  7998.     begin
  7999.       case Projection is
  8000.         when Stereographic |
  8001.              Gnomonic     |
  8002.              Lambert      => Umin := -2.0;
  8003.                              Umax :=  2.0;
  8004.                              Vmin := -2.0;
  8005.                              Vmax :=  2.0;
  8006.         when Orthographic |
  8007.              Satellite    => Umin := -1.0;
  8008.                              Umax :=  1.0;
  8009.                              Vmin := -1.0;
  8010.                              Vmax :=  1.0;
  8011.         when Azimuthal    |
  8012.              Mercator     => Umin := -180.0 * Radians_Per_Degree;
  8013.                              Umax := -Umin;
  8014.                              Vmin :=  Umin * 0.9;
  8015.                              Vmax :=  Umax;
  8016.         when Cartesian    => Umin := -180.0;
  8017.                              Umax :=  180.0;
  8018.                              Vmin :=  -90.0;
  8019.                              Vmax :=   90.0;
  8020.       end case;
  8021.     end Do_All_Earth;
  8022.  
  8023.     procedure Force_In_Bounds(Umin, Umax, Vmin, Vmax : in out float) is
  8024.     -- Given a projection such as orthographic, not all of the points can
  8025.     -- can be plotted for a given projection because they will be on the
  8026.     -- other side of the globe.  The user may zoom in by giving limits
  8027.     -- where some of them are on the other side of the globe.
  8028.     --   This routine adjusts to limits which are not visible by adjusting
  8029.     -- the limit to be on the horizon or the line between visibility and
  8030.     -- invisibility.
  8031.     begin
  8032.       if Umin >= Way_Out then
  8033.         case Projection is
  8034.           when Stereographic |
  8035.                Gnomonic      |
  8036.                Lambert      => Umin :=   -2.0;
  8037.           when Orthographic |
  8038.                Satellite    => Umin :=   -1.0;
  8039.           when Azimuthal    |
  8040.                Mercator     => Umin := -180.0 * Radians_Per_Degree;
  8041.           when Cartesian    => Umin := -180.0;
  8042.         end case;
  8043.       end if;
  8044.       if Umax >= Way_Out then
  8045.         case Projection is
  8046.           when Stereographic |
  8047.                Gnomonic      |
  8048.                Lambert      => Umax :=   2.0;
  8049.           when Orthographic |
  8050.                Satellite    => Umax :=   1.0;
  8051.           when Azimuthal    |
  8052.                Mercator     => Umax := 180.0 * Radians_Per_Degree;
  8053.           when Cartesian    => Umax := 180.0;
  8054.         end case;
  8055.       end if;
  8056.       if Vmin >= Way_Out then
  8057.         case Projection is
  8058.           when Stereographic |
  8059.                Gnomonic      |
  8060.                Lambert      => Vmin :=   -2.0;
  8061.           when Orthographic |
  8062.                Satellite    => Vmin :=   -1.0;
  8063.           when Azimuthal    |
  8064.                Mercator     => Vmin := -180.0 * Radians_Per_Degree;
  8065.           when Cartesian    => Vmin :=  -90.0;
  8066.         end case;
  8067.       end if;
  8068.       if Vmax >= Way_Out then
  8069.         case Projection is
  8070.           when Stereographic |
  8071.                Gnomonic      |
  8072.                Lambert      => Vmax :=   2.0;
  8073.           when Orthographic |
  8074.                Satellite    => Vmax :=   1.0;
  8075.           when Azimuthal    |
  8076.                Mercator     => Vmax := 180.0 * Radians_Per_Degree;
  8077.           when Cartesian    => Vmax :=  90.0;
  8078.         end case;
  8079.       end if;
  8080.     end Force_In_Bounds;
  8081.  
  8082.     procedure Do_Min_Max_Lat_Lon is
  8083.     -- Limits are defined by min/max latitudes and min/max longitudes.
  8084.       U1, V1, U2, V2 : float;
  8085.  
  8086.       function Max(X, Y : float) return float is
  8087.       begin
  8088.         if X > Y then
  8089.           return X;
  8090.         else
  8091.           return Y;
  8092.         end if;
  8093.       end Max;
  8094.  
  8095.       function Min(X, Y : float) return float is
  8096.       begin
  8097.         if X > Y then
  8098.           return Y;
  8099.         else
  8100.           return X;
  8101.         end if;
  8102.       end Min;
  8103.  
  8104.     begin  -- Do_Min_Max_Lat_Lon
  8105.       Lat_Pic_Min := Limits.Min_Lat_Lon.Y;
  8106.       Lat_Pic_Max := Limits.Max_Lat_Lon.Y;
  8107.       Lon_Pic_Min := Limits.Min_Lat_Lon.X;
  8108.       Lon_Pic_Max := Limits.Max_Lat_Lon.X;
  8109.       Project(Lat_Pic_Min, Lon_Pic_Min, U1, V1);
  8110.       Project(Lat_Pic_Max, Lon_Pic_Min, U2, V2);
  8111.       Force_In_Bounds(U1, V1, U2, V2);
  8112.       Vmin := Min(V1, V2);
  8113.       Vmax := Max(V1, V2);
  8114.       Umin := Min(U1, U2);
  8115.       Umax := Max(U1, U2);
  8116.     end Do_Min_Max_Lat_Lon;
  8117.  
  8118.     procedure Do_Min_Max_Coordinates is
  8119.     -- Limits are defined by two points of a rectangle, one in the upper
  8120.     -- right corner and one in the lower left corner.
  8121.       TUmin, TVmin, TUmax, TVmax : float;
  8122.  
  8123.       function Map(Val, Max_Val : float) return float is
  8124.       begin
  8125.         if Val > Max_Val then
  8126.           return Val - 2.0*Max_Val;
  8127.         else
  8128.           return Val;
  8129.         end if;
  8130.       end Map;
  8131.  
  8132.     begin  -- Do_Min_Max_Coordinates
  8133.       Lon_Pic_Min := Map(Limits.South_West.X, 180.0);
  8134.       Lon_Pic_Max := Map(Limits.North_East.X, 180.0);
  8135.       Lat_Pic_Min := Map(Limits.South_West.Y,  90.0);
  8136.       Lat_Pic_Max := Map(Limits.North_East.Y,  90.0);
  8137.       Project(Lat_Pic_Min, Lon_Pic_Min, TUmin, TVmin);
  8138.       Project(Lat_Pic_Max, Lon_Pic_Max, TUmax, TVmax);
  8139.       Force_In_Bounds(TUmin, TUmax, TVmin, TVmax);
  8140.       Umin := TUmin;
  8141.       Vmin := TVmin;
  8142.       Umax := TUmax;
  8143.       Vmax := TVmax;
  8144.     end Do_Min_Max_Coordinates;
  8145.  
  8146.     procedure Do_Angular is
  8147.     -- Limits are determined by earth central angles.
  8148.       TUmin   : float := Limits.Angle_Left;
  8149.       TUmax   : float := Limits.Angle_Right;
  8150.       TVmin   : float := Limits.Angle_Down;
  8151.       TVmax   : float := Limits.Angle_Up;
  8152.       CosUmin : constant float := Cos(TUmin * Radians_Per_Degree);
  8153.       SinUmin : constant float := Sqrt(1.0 + Eps - CosUmin*CosUmin);
  8154.       CosUmax : constant float := Cos(TUmax * Radians_Per_Degree);
  8155.       SinUmax : constant float := Sqrt(1.0 + Eps - CosUmax*CosUmax);
  8156.       CosVmin : constant float := Cos(TVmin * Radians_Per_Degree);
  8157.       SinVmin : constant float := Sqrt(1.0 + Eps - CosVmin*CosVmin);
  8158.       CosVmax : constant float := Cos(TVmax * Radians_Per_Degree);
  8159.       SinVmax : constant float := Sqrt(1.0 + Eps - CosVmax*CosVmax);
  8160.       Bad_Limits : exception;
  8161.     begin
  8162.       case Projection is
  8163.         when Stereographic =>
  8164.                Umin := -(1.0 - CosUmin) / SinUmin;
  8165.                Umax :=  (1.0 - CosUmax) / SinUmax;
  8166.                Vmin := -(1.0 - CosVmin) / SinVmin;
  8167.                Umax :=  (1.0 - CosUmax) / SinUmax;
  8168.         when Orthographic  =>
  8169.                if TUmin > 90.0 or
  8170.                   TUmax > 90.0 or
  8171.                   TVmin > 90.0 or
  8172.                   TUmax > 90.0 then
  8173.                  raise Bad_Limits;
  8174.                end if;
  8175.                Umin := -SinUmin;
  8176.                Umax :=  SinUmax;
  8177.                Vmin := -SinVmin;
  8178.                Vmax :=  SinVmax;
  8179.         when Gnomonic     =>
  8180.                if TUmin >= 90.0 or
  8181.                   TUmax >= 90.0 or
  8182.                   TVmin >= 90.0 or
  8183.                   TUmax >= 90.0 then
  8184.                  raise Bad_Limits;
  8185.                end if;
  8186.                Umin := -SinUmin / CosUmin;
  8187.                Umax :=  SinUmax / CosUmax;
  8188.                Vmin := -SinVmin / CosVmin;
  8189.                Vmax :=  SinVmax / CosVmax;
  8190.         when Lambert      =>
  8191.                TUmin := (1.0 + CosUmin) / SinUmin;
  8192.                Umin  := -2.0 / Sqrt(1.0 + TUmin*TUmin);
  8193.                TUmax := (1.0 + CosUmax) / SinUmax;
  8194.                Umax  :=  2.0 / Sqrt(1.0 + TUmax*TUmax);
  8195.                TVmin := (1.0 + CosVmin) / SinVmin;
  8196.                Vmin  := -2.0 / Sqrt(1.0 + TVmin*TVmin);
  8197.                TVmax := (1.0 + CosVmax) / SinVmax;
  8198.                Vmax  :=  2.0 / Sqrt(1.0 + TVmax*TVmax);
  8199.         when Azimuthal    =>
  8200.                Umin := -TUmin * Radians_Per_Degree;
  8201.                Umax :=  TUmax * Radians_Per_Degree;
  8202.                Vmin := -TVmin * Radians_Per_Degree;
  8203.                Vmax :=  TVmax * Radians_Per_Degree;
  8204.         when Cartesian    =>
  8205.                Umin := -TUmin;
  8206.                Umax :=  TUmax;
  8207.                Vmin := -TVmin;
  8208.                Vmax :=  TVmax;
  8209.         when Mercator     =>
  8210.                if TVmin >= 90.0 or
  8211.                   TUmax >= 90.0 then
  8212.                  raise Bad_Limits;
  8213.                end if;
  8214.                Umin := -TUmin * Radians_Per_Degree;
  8215.                Umax :=  TUmax * Radians_Per_Degree;
  8216.                Vmin := -Log((1.0+SinVmin) / CosVmin);
  8217.                Vmax :=  Log((1.0+SinVmax) / CosVmax);
  8218.         when Satellite    =>
  8219.                Umin := -1.0;
  8220.                Umax :=  1.0;
  8221.                Vmin := -1.0;
  8222.                Vmax :=  1.0;
  8223.       end case;
  8224.     exception
  8225.       when Bad_Limits =>
  8226.         Put_Line("Angular limits too great.  Plot aborted.");
  8227.         raise Caught_Error;
  8228.     end Do_Angular;
  8229.  
  8230.     procedure Do_Lat_Lon_Boundary is
  8231.     -- Limits are determined by four points, one on each of the four
  8232.     -- sides of a rectangle.
  8233.       U1, V1, U2, V2, U3, V3, U4, V4 : float;
  8234.     begin
  8235.       Lat_Pic_Min := Limits.Point_Down.Y;
  8236.       Lat_Pic_Max := Limits.Point_Up.Y;
  8237.       Lon_Pic_Min := Limits.Point_Left.X;
  8238.       Lon_Pic_Max := Limits.Point_Right.X;
  8239.       Project(Limits.Point_Left.Y,  Lon_Pic_Min,         U1, V1);
  8240.       Project(Lat_Pic_Min,          Limits.Point_Down.X, U2, V2);
  8241.       Project(Limits.Point_Right.Y, Lon_Pic_Max,         U3, V3);
  8242.       Project(Lat_Pic_Max,          Limits.Point_Up.X,   U4, V4);
  8243.       Force_In_Bounds(U1, U3, V2, V4);
  8244.       Umin := U1;
  8245.       Umax := U3;
  8246.       Vmin := V2;
  8247.       Vmax := V4;
  8248.     end Do_Lat_Lon_Boundary;
  8249.  
  8250.     procedure Do_Off_Center_Latitude is
  8251.     -- Set up for projections with centers off Latitude 0.0.
  8252.     begin
  8253.       case Projection is
  8254.         when Cartesian | Mercator =>
  8255.           if Phia = 0.0 and Proj_Params.Clk_Rot_Ar_Cent = 0.0 then
  8256.             SinO :=  1.0;
  8257.             CosO :=  0.0;
  8258.             SinR :=  0.0;
  8259.             CosR :=  1.0;
  8260.           elsif Phia = 0.0 and abs(Proj_Params.Clk_Rot_Ar_Cent) = 180.0 then
  8261.             Phio := Phio + 180.0;
  8262.             SinO := -1.0;
  8263.             CosO :=  0.0;
  8264.             SinR :=  0.0;
  8265.             CosR :=  1.0;
  8266.           else
  8267.             SinO1 := CosO*CosR;
  8268.             CosO1 := Sqrt(1.0 + Eps - SinO1*SinO1);
  8269.             Phio  := Phio - ATan2(SinR/CosO1, -CosR*SinO/CosO1)
  8270.                        * Degrees_Per_Radian;
  8271.             SinR  := SinR * CosO/CosO1;
  8272.             CosR  := -SinO/CosO1;
  8273.             SinO  := SinO1;
  8274.             CosO  := CosO1;
  8275.           end if;
  8276.         when others     => null;
  8277.       end case;
  8278.     end Do_Off_Center_Latitude;
  8279.  
  8280.     procedure Set_Scaling is
  8281.     -- Sets the windowing of the viewport.
  8282.     -- Also determines the maximum line to be drawn to avoid wraparound problems.
  8283.     -- Also determines the size of the symbols to be drawn.
  8284.       X_Max : constant float := 17.0; -- Maximum these can ever be under
  8285.       Y_Max : constant float := 11.0; --   any circumstances.
  8286.       Scale : constant Plot_Characteristics := Plot_Menu.Current_Plot_Char;
  8287.       Delta_U, Delta_V : float;
  8288.       Left, Bottom, Right, Top: float;
  8289.     begin
  8290.       Delta_U := abs(Umax - Umin);
  8291.       Delta_V := abs(Vmax - Vmin);
  8292.       if Delta_U*0.6 > Delta_V then
  8293.         Left   := Umin;
  8294.         Right  := Umax;
  8295.         Top    := (Vmin + Vmax) / 2.0;
  8296.         Bottom := Top;
  8297.         Symbol_Size := (Right - Left) * 0.6 / Symbol_Scale;
  8298.       else
  8299.         Top    := Vmax;
  8300.         Bottom := Vmin;
  8301.         Left   := (Umin + Umax) / 2.0;
  8302.         Right  := Left;
  8303.         Symbol_Size := (Top - Bottom) / Symbol_Scale;
  8304.       end if;
  8305.     -- Set View_Port here 
  8306.       Set_Window(Left, Bottom, Right, Top);
  8307.     -- calculate the length of a 30 degree line at the center of the projection
  8308.       Project(0.0, Proj_Params.Lon_Center-15.0, Left,  Top);
  8309.       Project(0.0, Proj_Params.Lon_Center+15.0, Right, Top);
  8310.     -- Make that the maximum length line drawable
  8311.       Max_Line := abs(Right - Left);
  8312.     end Set_Scaling;
  8313.  
  8314.   begin  -- Initialize_Plot
  8315.     Lat_Pic_Max :=   90.0;
  8316.     Lat_Pic_Min :=  -90.0;
  8317.     Lon_Pic_Max :=  180.0;
  8318.     Lon_Pic_Min := -180.0;
  8319.     Phia := Proj_Params.Lat_Center;
  8320.     Phio := Proj_Params.Lon_Center;
  8321.     SinR := Sin(Proj_Params.Clk_Rot_Ar_Cent * Radians_Per_Degree);
  8322.     CosR := Cos(Proj_Params.Clk_Rot_Ar_Cent * Radians_Per_Degree);
  8323.     SinO := Sin(Phia * Radians_Per_Degree);
  8324.     CosO := Cos(Phia * Radians_Per_Degree);
  8325.     Do_Off_Center_Latitude;
  8326.     case Type_Of_Projection_Limit is
  8327.       when All_Earth =>
  8328.         Do_All_Earth;
  8329.       when Min_Max_Lat_Lon =>
  8330.         Do_Min_Max_Lat_Lon;
  8331.       when Min_Max_Coordinates =>
  8332.         Do_Min_Max_Coordinates;
  8333.       when Angular_Dist_From_Projection_Center =>
  8334.         Do_Angular;
  8335.       when Lat_Lon_Boundary =>
  8336.         Do_Lat_Lon_Boundary;
  8337.     end case;      
  8338.     Set_Scaling;
  8339.   end Initialize_Plot;
  8340.  
  8341.   procedure Graff(NPts : in integer; U, V : in Float_Array;
  8342.                   Mode : in integer) is
  8343.   -- Plots arrays NPts points from U and V.
  8344.   -- Mode : 1 - Line plot
  8345.   --        2 - Point plot
  8346.   --        3 - connect every other point (for grids)
  8347.     Line_Mode  : constant := 1;
  8348.     Point_Mode : constant := 2;
  8349.     Dash_Mode  : constant := 3;
  8350.     Even       : boolean  := true;
  8351.  
  8352.     procedure Square(Center_X, Center_Y, Size : in float) is
  8353.       Half_Size : constant float := Size / 2.0;
  8354.     begin
  8355.       Move_To(Center_X + Half_Size, Center_Y + Half_Size);
  8356.       Line( Size, 0.0);
  8357.       Line(0.0, -Size);
  8358.       Line(-Size, 0.0);
  8359.       Line(0.0,  Size);
  8360.     end Square;
  8361.  
  8362.     procedure Plus(Center_X, Center_Y, Size : in float) is
  8363.       Half_Size : constant float := Size / 2.0;
  8364.     begin
  8365.       Move_To(Center_X - Half_Size, Center_Y);
  8366.       Line(Size, 0.0);
  8367.       Move_To(Center_X, Center_Y - Half_Size);
  8368.       Line(0.0, Size);
  8369.     end Plus;
  8370.  
  8371.     procedure Diamond(Center_X, Center_Y, Size : in float) is
  8372.       Half_Size : constant float := Size / 2.0;
  8373.       Horisize  : constant float := Half_Size * 0.75;
  8374.     begin
  8375.       Move_To(Center_X, Center_Y + Half_Size);
  8376.       Line( Horisize, -Half_Size);
  8377.       Line(-Horisize, -Half_Size);
  8378.       Line(-Horisize,  Half_Size);
  8379.       Line( Horisize,  Half_Size);
  8380.     end Diamond;
  8381.  
  8382.     procedure Triangle(Center_X, Center_Y, Size : in float) is
  8383.       Half_Size : constant float := Size / 2.0;
  8384.       Bottom    : constant float := Size * 0.433;
  8385.     begin
  8386.       Move_To(Center_X - Half_Size, Center_Y - Bottom);
  8387.       Line(Size, 0.0);
  8388.       Line(-Half_Size,  Size);
  8389.       Line(-Half_Size, -Size);
  8390.     end Triangle;
  8391.  
  8392.   begin  -- Graff
  8393.     Move_To(U(1), V(1));
  8394.     case Mode is
  8395.       when Line_Mode  => 
  8396.         for I in 2..NPts loop
  8397.           if abs(U(I) - U(I-1)) > Max_Line THEN
  8398.             Move_To(U(I), V(I));
  8399.           else
  8400.             Line_To(U(I), V(I));
  8401.           end if;
  8402.         end loop;
  8403.       when Point_Mode =>
  8404.         for I in 1 .. NPts loop
  8405.           case Symbol is
  8406.             when 1      => Square  (U(I), V(I), Symbol_Size);
  8407.             when 2      => Plus    (U(I), V(I), Symbol_Size);
  8408.             when 3      => Diamond (U(I), V(I), Symbol_Size);
  8409.             when others => Triangle(U(I), V(I), Symbol_Size);
  8410.           end case;
  8411.         end loop;
  8412.       when Dash_Mode  =>
  8413.         for I in 2..NPts loop
  8414.           if Even then
  8415.             if U(I-1) /= Way_Out then
  8416.               if abs(U(I) - U(I-1)) > Max_Line THEN
  8417.                 Move_To(U(I), V(I));
  8418.               else
  8419.                 Line_To(U(I), V(I));
  8420.               end if;
  8421.             end if;
  8422.           else
  8423.             Move_To(U(I), V(I));
  8424.           end if;
  8425.           Even := not Even;
  8426.         end loop;
  8427.       when others => null;
  8428.     end case;
  8429.   end Graff;
  8430.  
  8431.   procedure Plot_Points(Points_Type : Beam_Or_Symbol; Name_Length : integer;
  8432.                         File_Name : FileName; Draw_Color : Color_Type) is
  8433.   -- Plots map, beam, and symbol data.
  8434.   use World_Data_Files;
  8435.     Lat_Lon : Lat_Lon_Record;
  8436.     Point_File : World_Data_Io.File_Type;
  8437.  
  8438.     procedure Plot_Rec(Rec : Lat_Lon_Record) is
  8439.       Stop : constant integer := 2 * Lat_Lon.Number_Of_Pairs;
  8440.       N, I, NPts : integer;
  8441.       Draw_Mode  : integer;
  8442.       ProjU, ProjV : Float_Array;
  8443.     begin
  8444.       if Points_Type = Symbol_Data then
  8445.         Draw_Mode := 2;
  8446.       else
  8447.         Draw_Mode := 1;
  8448.       end if;
  8449.       NPts := 0;
  8450.       I    := 1;
  8451.       loop
  8452.         exit when I > Stop;
  8453.         NPts := NPts + 1;
  8454.         Project(Lat_Lon.Lat_Lon_Pairs(I), Lat_Lon.Lat_Lon_Pairs(I+1),
  8455.                 ProjU(NPts), ProjV(NPts));
  8456.         if NPts = Max_Points then
  8457.           Graff(Max_Points, ProjU, ProjV, Draw_Mode);
  8458.           ProjU(1) := ProjU(Max_Points);
  8459.           ProjV(1) := ProjV(Max_Points);
  8460.           NPts     := 1;
  8461.         end if;
  8462.         I := I + 2;
  8463.       end loop;
  8464.       if NPts > 1 then
  8465.         Graff(NPts, ProjU, ProjV, Draw_Mode);
  8466.       end if;
  8467.     end Plot_Rec;
  8468.  
  8469.     function In_View return boolean is
  8470.     -- Determines whether or not the current record will be visible
  8471.     -- in the window.
  8472.       Lat_Min : constant float := Lat_Lon.Minimum_Lat;
  8473.       Lat_Max : constant float := Lat_Lon.Maximum_Lat;
  8474.       Lon_Min :          float := Lat_Lon.Minimum_Lon;
  8475.       Lon_Max :          float := Lat_Lon.Maximum_Lon;
  8476.     begin
  8477.       if Lon_Max > 180.0 then
  8478.         Lon_Min := Lon_Min - 180.0;
  8479.         Lon_Max := Lon_Max - 180.0;
  8480.       end if;
  8481.       if Lat_Min >= Lat_Pic_Max or else
  8482.          Lon_Min >= Lon_Pic_Max or else
  8483.          Lat_Max <= Lat_Pic_Min or else
  8484.          Lon_Max <= Lon_Pic_Min then
  8485.         return false;
  8486.       else
  8487.         return true;
  8488.       end if;
  8489.     end In_View;
  8490.  
  8491.   begin  -- Plot_Points
  8492.     if Points_Type = Map_Data then
  8493.       Put_Line("Plotting Map...");
  8494.     elsif Points_Type = Beam_Data then
  8495.       Put_Line("Plotting Beam Data...");
  8496.     else
  8497.       Put_Line("Plotting Symbol Data...");
  8498.     end if;
  8499.     World_Data_Io.Open(Point_File, World_Data_Io.in_file,
  8500.                        File_Name(1..Name_Length), "");
  8501.     Set_Mode(Graphics);
  8502.     Set_Color(Draw_Color);
  8503.     while not World_Data_Io.end_of_file(Point_File) loop
  8504.       World_Data_Io.Read(Point_File, Lat_Lon);
  8505.       if Points_Type = Symbol_Data  then
  8506.         Symbol := integer(Lat_Lon.Minimum_Lat);
  8507.         Plot_Rec(Lat_Lon);
  8508.       elsif In_View then
  8509.         Plot_Rec(Lat_Lon);
  8510.       end if;
  8511.     end loop;
  8512.     Set_Mode(Text);
  8513.   exception
  8514.     when World_Data_Io.Name_Error =>
  8515.       if Points_Type = Map_Data then
  8516.         Put_Line("Map file not found.");
  8517.       elsif Points_Type = Beam_Data then
  8518.         Put_Line("Beam file not found.");
  8519.       else
  8520.         Put_Line("Symbol file not found.");
  8521.       end if;
  8522.   end Plot_Points;
  8523.  
  8524.   procedure Draw_Limb is
  8525.   -- Draws Limb line around map.
  8526.     Segments : constant integer := 73; -- 5 degree increments (360/5 + 1)
  8527.     Sin1 : constant float := 8.71557420E-2; -- sin(360/(Segments-1))
  8528.     Cos1 : constant float := 9.96194698E-1; -- cos(360/(Segments-1))
  8529.     Radius, Axis, D, Angle : float;
  8530.     ProjU, ProjV : Float_Array;
  8531.     N : integer;
  8532.     Invalid_Operation : exception;
  8533.   begin
  8534.     Axis := 1.0;
  8535.     Case Projection is
  8536.       when Orthographic =>
  8537.         Radius := 1.0;
  8538.       when Satellite    =>
  8539.         D      := Proj_Params.Sat_Altitude / 3444.0;
  8540.         Radius := D * Sat_Scale(Proj_Params.Sat_Altitude,
  8541.                                 Proj_Params.View_Altitude)
  8542.                     * ASin(1.0/(D+1.0));
  8543.       when Lambert      =>
  8544.         Radius := 2.0;
  8545.       when Azimuthal    =>
  8546.         Radius := Pi;
  8547.       when others       =>
  8548.         raise Invalid_Operation;
  8549.     end case;
  8550.     ProjU(1) := Radius;
  8551.     ProjV(1) := 0.0;
  8552.     N := 1;
  8553.     Angle := 0.0;
  8554.     Set_Mode(Graphics);
  8555.     Set_Color(Map_Color.Map_Outline);
  8556.     for I in 1 .. Segments loop
  8557.       N := N + 1;
  8558.       Angle    := Angle + 0.087266462;
  8559.       ProjU(N) := Radius*Cos(Angle);
  8560.       ProjV(N) := Radius*Sin(Angle);
  8561.       if N = Max_Points then
  8562.         Graff(N, ProjU, ProjV, 1);
  8563.         ProjU(1) := ProjU(N);
  8564.         ProjV(1) := ProjV(N);
  8565.         N := 1;
  8566.       end if;
  8567.     end loop;
  8568.     if N /= 1 then
  8569.       Graff(N, ProjU, ProjV, 1);
  8570.     end if;
  8571.     Set_Mode(Text);
  8572.   exception
  8573.     when Invalid_Operation => N := 0; -- null;
  8574.   end Draw_Limb;
  8575.  
  8576.   procedure Draw_Grids is
  8577.   -- Draws the grid lines on the map.
  8578.     Grid_Rec     : constant Grid_Line_Parameters
  8579.                      := Plot_Menu.Current_Grid_Line_Parameters;
  8580.     Lat_Initial  : constant float   :=  -90.0;
  8581.     Lat_Final    : constant float   :=   89.0;
  8582.     Lon_Initial  : constant float   := -180.0;
  8583.     Lon_Final    : constant float   :=  180.0;
  8584.     Increment    : constant float   := Grid_Rec.Segment_Length;
  8585.     Grid_Lat     : constant float   := Grid_Rec.Degrees_Btwn_Lats;
  8586.     Grid_Lon     : constant float   := Grid_Rec.Degrees_Btwn_Lons;
  8587.     S_Lat        : constant float   :=    7.5;
  8588.     A_Lon        : constant integer :=   90;
  8589.     ProjU, ProjV : Float_Array;
  8590.     X_Lat, X_Lon : float;
  8591.     Lat_Stop     : float;
  8592.     NPts         : integer;
  8593.  
  8594.     procedure Reset is
  8595.     begin
  8596.       NPts := 0;
  8597.       if integer(X_Lon) mod A_Lon = 0 then
  8598.         X_Lat    := Lat_Initial + S_Lat;
  8599.         Lat_Stop := Lat_Final   - S_Lat;
  8600.       else
  8601.         X_Lat    := Lat_Initial;
  8602.         Lat_Stop := Lat_Final;
  8603.       end if;
  8604.     end Reset;
  8605.  
  8606.   begin  -- Draw_Grids
  8607.     Set_Mode(Graphics);
  8608.     Set_Color(Map_Color.Grid_Lines);
  8609.     if Grid_Lat /= 0.0 then
  8610.       X_Lat := Lat_Initial + Grid_Lat;
  8611.       X_Lon := Lon_Initial;
  8612.       NPts  := 0;
  8613.       loop
  8614.         NPts := NPts + 1;
  8615.         Project(X_Lat, X_Lon, ProjU(NPts), ProjV(NPts));
  8616.         X_Lon := X_Lon + Increment;
  8617.         if X_Lon > Lon_Final then
  8618.           Graff(NPts, ProjU, ProjV, 3);
  8619.           X_Lat := X_Lat + Grid_Lat;
  8620.           exit when X_Lat > Lat_Final;
  8621.           X_Lon := Lon_Initial;
  8622.           NPts  := 0;
  8623.         end if;
  8624.       end loop;
  8625.     end if;
  8626.     if Grid_Lon /= 0.0 then
  8627.       X_Lon := Lon_Initial + Grid_Lon;
  8628.       Reset;
  8629.       loop
  8630.         NPts := NPts + 1;
  8631.         Project(X_Lat, X_Lon, ProjU(NPts), ProjV(NPts));
  8632.         X_Lat := X_Lat + Increment;
  8633.         if X_Lat > Lat_Stop then
  8634.           Graff(NPts, ProjU, ProjV, 3);
  8635.           X_Lon := X_Lon + Grid_Lon;
  8636.           exit when X_Lon > Lon_Final;
  8637.           Reset;
  8638.         end if;
  8639.       end loop;
  8640.     end if;
  8641.     Set_Mode(Text);
  8642.   end Draw_Grids;
  8643.  
  8644. begin  -- Draw_Map
  8645.   Proj_Params := Plot_Menu.Current_Projection_Parameters;
  8646.   Initialize_Plot;
  8647.   if Plot_Land then
  8648.     Plot_Points(Map_Data, Specials.Points_Last,
  8649.                 Specials.Points_Data, Specials.Points_Color);
  8650.   end if;
  8651.   Draw_Limb;
  8652.   if Show_Grid then
  8653.     Draw_Grids;
  8654.   end if;
  8655.   if Show_Beam then
  8656.     Plot_Points(Beam_Data, Specials.Beam_Last,
  8657.                 Specials.Beam_Data,  Specials.Beam_Color);
  8658.   end if;
  8659.   if Show_Swath then
  8660.     Plot_Points(Symbol_Data, Specials.Swath_Last,
  8661.                 Specials.Swath_Data, Specials.Swath_Color);
  8662.   end if;
  8663. exception
  8664.   when Caught_Error     =>
  8665.     null;
  8666.   when Constraint_Error =>
  8667.     Put_Line("Constraint Error");
  8668.   when Numeric_Error    =>
  8669.     Put_Line("Numeric Error");
  8670.   when Storage_Error    =>
  8671.     Put_Line("Storage Error");
  8672.   when Tasking_Error    =>
  8673.     Put_Line("Tasking Error");
  8674.   when others => null;
  8675.     Put_Line("Unknown Error");
  8676. end Draw_Map;
  8677.  
  8678. begin  -- World
  8679.   Create_Port(Map, 5, 5, 100, 45);
  8680.   loop
  8681.     Select_Port(Map);
  8682.     Put("Session Menu Filename=> ");
  8683.     Get_Line(Namer, Laster);
  8684.     exit when Laster = 0;
  8685.     Open_Menu_File( namer(1 .. laster) );
  8686.     Read_Session_Defaults;
  8687.     Close_Menu_File;
  8688.     Select_Port(Map);
  8689.     Draw_Map;
  8690.     Frame_Port;
  8691.     Put_line("Building Plot File...");
  8692.     Print_Screen("Map.lis");
  8693.     Put_Line("Plot file built");
  8694.     Erase_Screen;
  8695.   end loop;
  8696.   Put_Line("Ending plot generation");
  8697. end Plot;
  8698. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8699. --pointsrea.txt
  8700. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8701. with TEXT_IO, WORLD_DATA_FILES;
  8702. use  TEXT_IO, WORLD_DATA_FILES;
  8703. pragma elaborate (WORLD_DATA_FILES);
  8704.  
  8705. procedure POINTS_READ is
  8706.  
  8707.   FORT_BUF      :      string ( 1 .. 80 ) := 
  8708.     "**********" &     "**********" &     "**********" &     "**********" & 
  8709.     "**********" &     "**********" &     "**********" &     "**********";
  8710.   FORT_FILE     :      FILE_TYPE;
  8711.   LAT_FILE      :      World_DATA_IO.FILE_TYPE;
  8712.   LAST_ONE      :      integer      := 0;
  8713.   RESULT        :      integer;
  8714.   RESULT_FLOAT  :      float      := 0.0;
  8715.   CURRENT_RECORD:      lat_lon_record;
  8716.   FIlE_NAME_INP :      string ( 1 .. 20 ) := "                    ";
  8717.   LONGITUDE     :      constant integer := 1;
  8718.   LATITUDE      :      constant integer := 0;
  8719.   PAIR          :      integer range 1 .. MAXIMUM_LAT_LON_PAIRS;
  8720.   LAST_COUNT    :      integer := MAXIMUM_LAT_LON_PAIRS;
  8721.  
  8722.   package INT_IO is new INTEGER_IO ( integer );
  8723.   package FLT_IO is new FLOAT_IO   ( float   );
  8724.  
  8725. begin
  8726.  
  8727.   PUT ( "Point file to read : " );
  8728.   GET_LINE ( FILE_NAME_INP, LAST_ONE );
  8729.   OPEN ( FORT_FILE, IN_FILE, FILE_NAME_INP(1..20));
  8730.   PUT ( "World Data File to Create : " );
  8731.   GET_LINE ( FILE_NAME_INP, LAST_ONE );
  8732.   WORLD_DATA_IO.CREATE ( LAT_FILE, WORLD_DATA_IO.OUT_FILE, 
  8733.                          FILE_NAME_INP ( 1 .. LAST_ONE ) );
  8734.   WORLD_DATA_IO.SET_INDEX ( LAT_FILE, WORLD_DATA_IO.POSITIVE_COUNT ( 1 ) );
  8735.   while not end_of_file ( fort_file ) loop
  8736.  
  8737.     --
  8738.     -- INIT CURRENT RECORD;
  8739.     --
  8740.     CURRENT_RECORD.MINIMUM_LAT := 0.0;
  8741.     CURRENT_RECORD.MAXIMUM_LAT := 0.0;
  8742.     CURRENT_RECORD.MINIMUM_LON := 0.0;
  8743.     CURRENT_RECORD.MAXIMUM_LON := 0.0;
  8744.     for I in 1 .. LAST_COUNT loop
  8745.      current_record.lat_lon_pairs(I) := 0.0;
  8746.     end loop;
  8747.     LAST_COUNT := 0;
  8748.  
  8749.     --
  8750.     -- Get Irec.
  8751.     --
  8752.     GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8753.     INT_IO.GET ( FORt_buf ( 1 .. LAST_ONE ), RESULT, LAST_ONE );
  8754.     PUT ( "IREC => " ); INT_IO.PUT ( RESULT ); 
  8755.     WORLD_DATA_IO.SET_INDEX ( LAT_FILE, WORLD_DATA_IO.POSITIVE_COUNT (RESULT) );
  8756.     --
  8757.     -- Get Number of lat lon pairs.
  8758.     --
  8759.     GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8760.     INT_IO.GET ( FORt_buf ( 1 .. LAST_ONE ), RESULT, LAST_ONE );
  8761.     PUT ( "  NUMBER OF LAT LON PAIRS => "); INT_IO.PUT ( RESULT ); 
  8762.     CURRENT_RECORD.NUMBER_OF_PAIRS := RESULT;    
  8763.     PAIR := 1;
  8764.     loop
  8765. --
  8766. --      1st float.
  8767. --
  8768.       GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8769.       flt_io.get ( FORT_BUF ( 1 .. LAST_ONE ), RESULT_FLOAT, LAST_ONE );
  8770.       CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LATITUDE) := RESULT_FLOAT;
  8771. --
  8772. --      2nd float.
  8773. --
  8774.       GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8775.       flt_io.get ( FORT_BUF ( 1 .. LAST_ONE ), RESULT_FLOAT, LAST_ONE );
  8776.       CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LONGITUDE) := RESULT_FLOAT;
  8777.       LAST_COUNT := LAST_COUNT + 2;
  8778. --
  8779. --      Blank line
  8780. --
  8781.       GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8782.  
  8783.       if PAIR = 1 then
  8784.        CURRENT_RECORD.MINIMUM_LAT := current_record.lat_lon_pairs(1 + latitude
  8785. );
  8786.        CURRENT_RECORD.MAXIMUM_LAT := current_record.lat_lon_pairs(1 + latitude
  8787. );
  8788.        CURRENT_RECORD.MINIMUM_LON := current_record.lat_lon_pairs(1 + longitude
  8789. );
  8790.        CURRENT_RECORD.MAXIMUM_LON := current_record.lat_lon_pairs(1 + longitude
  8791. );
  8792.       else
  8793.        if CURRENT_RECORD.MINIMUM_LAT >
  8794.         CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LATITUDE) then
  8795.         CURRENT_RECORD.MINIMUM_LAT := CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LATITUDE);
  8796.        end if;
  8797.        if CURRENT_RECORD.MAXIMUM_LAT <
  8798.         CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LATITUDE) then
  8799.         CURRENT_RECORD.MAXIMUM_LAT := CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LATITUDE);
  8800.        end if;
  8801.        if CURRENT_RECORD.MINIMUM_LON >
  8802.         CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LONGITUDE) then
  8803.         CURRENT_RECORD.MINIMUM_LON := CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LONGITUDE);
  8804.        end if;
  8805.        if CURRENT_RECORD.MAXIMUM_LON <
  8806.         CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LONGITUDE) then
  8807.         CURRENT_RECORD.MAXIMUM_LON := CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LONGITUDE);
  8808.        end if;
  8809.      end if;
  8810.     exit when (PAIR + 1)/2 = RESULT;
  8811.     PAIR := PAIR + 2;
  8812.     end loop;  
  8813.     WORLD_DATA_IO.WRITE ( LAT_FILE, CURRENT_RECORD );
  8814.     NEW_LINE;
  8815.   end loop;
  8816.   CLOSE ( FORT_FILE );
  8817.   WORLD_DATA_IO.CLOSE ( LAT_FILE ); 
  8818.  
  8819. end POINTS_READ;
  8820. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8821. --symbolrea.txt
  8822. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8823. with TEXT_IO, WORLD_DATA_FILES;
  8824. use  TEXT_IO, WORLD_DATA_FILES;
  8825. pragma elaborate (WORLD_DATA_FILES);
  8826.  
  8827. procedure SYMBOL_READ is
  8828.  
  8829.   FORT_BUF      :      string ( 1 .. 80 ) := 
  8830.     "**********" &     "**********" &     "**********" &     "**********" & 
  8831.     "**********" &     "**********" &     "**********" &     "**********";
  8832.   FORT_FILE     :      FILE_TYPE;
  8833.   LAT_FILE      :      World_DATA_IO.FILE_TYPE;
  8834.   LAST_ONE      :      integer      := 0;
  8835.   RESULT        :      integer;
  8836.   RESULT_FLOAT  :      float      := 0.0;
  8837.   CURRENT_RECORD:      lat_lon_record;
  8838.   FIlE_NAME_INP :      string ( 1 .. 20 ) := "                    ";
  8839.   LONGITUDE     :      constant integer := 1;
  8840.   LATITUDE      :      constant integer := 0;
  8841.   PAIR          :      integer range 1 .. MAXIMUM_LAT_LON_PAIRS;
  8842.   LAST_COUNT    :      integer := MAXIMUM_LAT_LON_PAIRS;
  8843.  
  8844.   package INT_IO is new INTEGER_IO ( integer );
  8845.   package FLT_IO is new FLOAT_IO   ( float   );
  8846.  
  8847. begin
  8848.  
  8849.   PUT ( "Point file to read : " );
  8850.   GET_LINE ( FILE_NAME_INP, LAST_ONE );
  8851.   OPEN ( FORT_FILE, IN_FILE, FILE_NAME_INP(1..20));
  8852.   PUT ( "World Data File to Create : " );
  8853.   GET_LINE ( FILE_NAME_INP, LAST_ONE );
  8854.   WORLD_DATA_IO.CREATE ( LAT_FILE, WORLD_DATA_IO.OUT_FILE, 
  8855.                          FILE_NAME_INP ( 1 .. LAST_ONE ) );
  8856.   WORLD_DATA_IO.SET_INDEX ( LAT_FILE, WORLD_DATA_IO.POSITIVE_COUNT ( 1 ) );
  8857.   while not end_of_file ( fort_file ) loop
  8858.  
  8859.     --
  8860.     -- INIT CURRENT RECORD;
  8861.     --
  8862.     CURRENT_RECORD.MINIMUM_LAT := 0.0;
  8863.     CURRENT_RECORD.MAXIMUM_LAT := 0.0;
  8864.     CURRENT_RECORD.MINIMUM_LON := 0.0;
  8865.     CURRENT_RECORD.MAXIMUM_LON := 0.0;
  8866.     for I in 1 .. LAST_COUNT loop
  8867.      current_record.lat_lon_pairs(I) := 0.0;
  8868.     end loop;
  8869.     LAST_COUNT := 0;
  8870.  
  8871.     --
  8872.     -- Get Irec.
  8873.     --
  8874.     GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8875.     INT_IO.GET ( FORt_buf ( 1 .. LAST_ONE ), RESULT, LAST_ONE );
  8876.     PUT ( "IREC => " ); INT_IO.PUT ( RESULT ); 
  8877.     WORLD_DATA_IO.SET_INDEX ( LAT_FILE, WORLD_DATA_IO.POSITIVE_COUNT (RESULT) );
  8878.     --
  8879.     --  Get symbol type.
  8880.     --
  8881.       GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8882.       flt_io.get ( FORT_BUF ( 1 .. LAST_ONE ), RESULT_FLOAT, LAST_ONE );
  8883.       CURRENT_RECORD.MINIMUM_LAT := RESULT_FLOAT;
  8884.     --
  8885.     -- Get Number of lat lon pairs.
  8886.     --
  8887.     GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8888.     INT_IO.GET ( FORt_buf ( 1 .. LAST_ONE ), RESULT, LAST_ONE );
  8889.     PUT ( "  NUMBER OF LAT LON PAIRS => "); INT_IO.PUT ( RESULT ); 
  8890.     CURRENT_RECORD.NUMBER_OF_PAIRS := RESULT;    
  8891.     PAIR := 1;
  8892.     loop
  8893. --
  8894. --      1st float.
  8895. --
  8896.       GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8897.       flt_io.get ( FORT_BUF ( 1 .. LAST_ONE ), RESULT_FLOAT, LAST_ONE );
  8898.       CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LATITUDE) := RESULT_FLOAT;
  8899. --
  8900. --      2nd float.
  8901. --
  8902.       GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8903.       flt_io.get ( FORT_BUF ( 1 .. LAST_ONE ), RESULT_FLOAT, LAST_ONE );
  8904.       CURRENT_RECORD.LAT_LON_PAIRS(PAIR + LONGITUDE) := RESULT_FLOAT;
  8905.       LAST_COUNT := LAST_COUNT + 2;
  8906. --
  8907. --      Blank line
  8908. --
  8909.       GET_LINE ( FORT_FILE, FORT_BUF , LAST_ONE );
  8910.  
  8911.     exit when (PAIR + 1)/2 = RESULT;
  8912.     PAIR := PAIR + 2;
  8913.     end loop;  
  8914.     WORLD_DATA_IO.WRITE ( LAT_FILE, CURRENT_RECORD );
  8915.     NEW_LINE;
  8916.   end loop;
  8917.   CLOSE ( FORT_FILE );
  8918.   WORLD_DATA_IO.CLOSE ( LAT_FILE ); 
  8919.  
  8920. end SYMBOL_READ;
  8921. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8922. --symbolmer.txt
  8923. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8924. with TEXT_IO, WORLD_DATA_FILES;
  8925. use  TEXT_IO, WORLD_DATA_FILES;
  8926. pragma elaborate (WORLD_DATA_FILES);
  8927.  
  8928. procedure SYMBOL_MERGE is
  8929.  
  8930.   NEW_FILE      :      World_DATA_IO.FILE_TYPE;
  8931.   OLD_FILE      :      World_DATA_IO.FILE_TYPE;
  8932.   
  8933.   LAST_ONE      :      integer      := 0;
  8934.   CURRENT_RECORD:      lat_lon_record;
  8935.   FIlE_NAME_INP :      string ( 1 .. 80 ) := ( 1 .. 80 => ' ' );
  8936.  
  8937. begin
  8938.  
  8939.   PUT ( "World Symbol File to Create : " );
  8940.   GET_LINE ( FILE_NAME_INP, LAST_ONE );
  8941.  
  8942.   WORLD_DATA_IO.CREATE ( NEW_FILE, WORLD_DATA_IO.OUT_FILE, 
  8943.                          FILE_NAME_INP ( 1 .. LAST_ONE ) );
  8944.   WORLD_DATA_IO.SET_INDEX ( NEW_FILE, WORLD_DATA_IO.POSITIVE_COUNT ( 1 ) );
  8945.  
  8946.   PUT ( "World symbol file to merge: " );
  8947.   GET_LINE ( FILE_NAME_INP, LAST_ONE );
  8948.  
  8949.   while LAST_ONE /= 0 loop
  8950.     WORLD_DATA_IO.OPEN ( OLD_FILE, WORLD_DATA_IO.IN_FILE,
  8951.                           FILE_NAME_INP ( 1 .. LAST_ONE ) );
  8952.     while not WORLD_DATA_IO.END_OF_FILE ( OLD_FILE ) loop
  8953.       WORLD_DATA_IO.READ ( OLD_FILE, CURRENT_RECORD );
  8954.       WORLD_DATA_IO.WRITE ( NEW_FILE, CURRENT_RECORD );
  8955.     end loop;
  8956.     WORLD_DATA_IO.CLOSE ( OLD_FILE );
  8957.     PUT ( "World symbol file to merge: " );
  8958.     GET_LINE ( FILE_NAME_INP, LAST_ONE );
  8959.   end loop;
  8960.   WORLD_DATA_IO.CLOSE ( NEW_FILE );
  8961.    
  8962. end SYMBOL_MERGE;
  8963.  
  8964.