DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ B T ┃
Length: 43935 (0xab9f) Types: TextFile Names: »B«
└─⟦85b835f43⟧ Bits:30000549 8mm tape, Rational 1000, Xlib rev 6.00 └─ ⟦0c20f784e⟧ »DATA« └─⟦1abbe589f⟧ └─⟦306851c02⟧ └─⟦this⟧
with Calendar; with Text_Io; with Ico_Objcube; use Ico_Objcube; with Ico_Objico; use Ico_Objico; with Ico_Objtetra; use Ico_Objtetra; with Ico_Polyinfo; use Ico_Polyinfo; with Ran1_Package; use Ran1_Package; with Trig; with Xlbt_Arithmetic; use Xlbt_Arithmetic; with Xlbt_Atom_Defs; use Xlbt_Atom_Defs; with Xlbt_Basic; use Xlbt_Basic; with Xlbt_Color; use Xlbt_Color; with Xlbt_Event; use Xlbt_Event; with Xlbt_Gc; use Xlbt_Gc; with Xlbt_Geometry; use Xlbt_Geometry; with Xlbt_Graphics; use Xlbt_Graphics; with Xlbt_Pointer; use Xlbt_Pointer; with Xlbt_String; use Xlbt_String; with Xlbt_Window; use Xlbt_Window; with Xlbp_Color; use Xlbp_Color; with Xlbp_Display; use Xlbp_Display; with Xlbp_Event; use Xlbp_Event; with Xlbp_Gc; use Xlbp_Gc; with Xlbp_Geometry; use Xlbp_Geometry; with Xlbp_Graphics; use Xlbp_Graphics; with Xlbp_Sync; use Xlbp_Sync; with Xlbp_Window; use Xlbp_Window; with Xlbp_Window_Information; use Xlbp_Window_Information; with Xlbp_Window_Property; use Xlbp_Window_Property; package body Ico_Main is ------------------------------------------------------------------------------ -- Derived from: ico.c ------------------------------------------------------------------------------ -- $Header: ico.c,v 1.4 88/02/09 13:15:08 jim Exp $ ------------------------------------------------------------------------------ -- Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, -- and the Massachusetts Institute of Technology, Cambridge, Massachusetts. -- -- All Rights Reserved -- -- Permission to use, copy, modify, and distribute this software and its -- documentation for any purpose and without fee is hereby granted, -- provided that the above copyright notice appear in all copies and that -- both that copyright notice and this permission notice appear in -- supporting documentation, and that the names of Digital or MIT not be -- used in advertising or publicity pertaining to distribution of the -- software without specific, written prior permission. -- -- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -- SOFTWARE. -- ------------------------------------------------------------------------------ -- -- Description -- Display a wire-frame rotating icosahedron, with hidden lines removed -- -- Arguments: -- -r display on root window instead of creating a new one -- =wxh+x+y X geometry for new window (default 600x600 centered) -- host:display X display on which to run -- (plus a host of others, try -help) ------------------------------------------------------------------------------ -- Additions by jimmc@sci: -- faces and colors -- double buffering on the display -- additional polyhedra -- sleep switch ------------------------------------------------------------------------------ Ico_Fatal_Error : exception; Ran_Data : Ran1_Data; type Transform_3d is array (0 .. 3, 0 .. 3) of Float; ----Now include all the files which define the actual polyhedra type Poly_Info_Pointer is access Poly_Info; type Poly_Info_Array is array (Natural range <>) of Poly_Info_Pointer; Polys : constant Poly_Info_Array := (1 => new Poly_Info'(Obj_Cube), 2 => new Poly_Info'(Obj_Ico), 3 => new Poly_Info'(Obj_Tetra)); type Xx_Color_List is access X_Color_Array; type Xx_Pixel_List is access X_Pixel_Array; type Xx_Plane_Mask_List is access X_Plane_Mask_Array; type Xx_String_Pointer_List is access X_String_Pointer_Array; type Dbuf_Info is record Prev_X : S_Short; Prev_Y : S_Short; Plane_Masks : S_Natural; -- points into dbpain.plane_masks En_Plane_Mask : X_Plane_Mask; -- what we enable for drawing Colors : Xx_Color_List; -- size = 2 ** totalplanes Pixels : Xx_Pixel_List; -- size = 2 ** planesperbuf end record; type Dbuf_Info_Array is array (S_Natural range <>) of Dbuf_Info; type Dbuf_Pair is record Planes_Per_Buf : S_Natural; Pixels_Per_Buf : S_Natural; -- = 1<<planesperbuf Total_Planes : S_Natural; -- = 2*planesperbuf Total_Pixels : S_Natural; -- = 1<<totalplanes Plane_Masks : Xx_Plane_Mask_List; -- size = totalplanes Pixels : X_Pixel_Array (0 .. 0); Dbuf_Num : S_Natural; Bufs : Dbuf_Info_Array (0 .. 1); Draw_Buf : S_Natural; Dpy_Buf : S_Natural; end record; Dbpair : Dbuf_Pair; type S_Char_Array_2d is array (S_Natural range <>, S_Natural range <>) of S_Char; Drawn : S_Char_Array_2d (0 .. Max_Nv - 1, 0 .. Max_Nv - 1); Zero : constant S_Char_Array_2d (0 .. Max_Nv - 1, 0 .. Max_Nv - 1) := (others => (others => 0)); Bg_Color : X_Color; Fg_Color : X_Color; Dpy : X_Display; Win : X_Window; Win_Width : U_Short; Win_Height : U_Short; Cmap : X_Colormap; Gc : X_Gc; Initialized : Boolean := False; Dsync : Boolean := False;-- call X_Sync to keep things debuggable Dblbuf : Boolean := False;-- do double buffering Sleepcount : Duration; -- how long to sleep between draws Isleepcount : Duration := 5.0; -- heuristic sleep period Numcolors : S_Natural := 0; -- Number of colors user asked for Colornames : Xx_String_Pointer_List; Dofaces : Boolean := False;-- draw faces on screen? Doedges : Boolean := True; -- draw edges on screen? Xform : Transform_3d; Xv : Point_3d_Array_2d; Buffer : Boolean; Wo2 : Float; Ho2 : Float; --\f ------------------------------------------------------------------------------ -- Forward Declarations ------------------------------------------------------------------------------ procedure Concat_Mat (L : Transform_3d; R : Transform_3d; M : in out Transform_3d); procedure Draw_Poly (Poly : Poly_Info_Pointer; Win : X_Window; Gc : X_Gc; Icox : S_Short; Icoy : S_Short; Icow : U_Short; Icoh : U_Short; Prevx : S_Short; Prevy : S_Short); function Find_Poly (Name : String) return Poly_Info_Pointer; procedure Format_Rotate_Mat (Axis : Character; Angle : Float; M : in out Transform_3d); procedure Give_Obj_Help; procedure Ico_Fatal (Fmt : String); procedure Ident_Mat (M : in out Transform_3d); procedure Init_Dbufs (Fg : X_Pixel; Bg : X_Pixel; Planes_Per_Buf : Natural); procedure Partial_Non_Hom_Transform (N : S_Natural; M : Transform_3d; Inn : Point_3d_Array; Outt : in out Point_3d_Array); procedure Set_Buf_Color (N : S_Natural; -- color index Color : X_Color); -- color to set procedure Set_Buf_Colname (N : S_Natural; Colname : X_String); procedure Set_Display_Buf (N : S_Natural); procedure Set_Draw_Buf (N : S_Natural); -- static char *help_message() = { -- "where options include:", -- " -display host:dpy X server to use", -- " -geometry geom geometry of window to use", -- " -r draw in the root window", -- " -d number dashed line pattern for wire frames", -- " -colors color ... codes to use on sides", -- " -dbl use double buffering", -- " -noedges don't draw wire frame edges", -- " -faces draw faces", -- " -i invert", -- " -sleep number seconds to sleep in between draws", -- " -obj objname type of polyhedral object to draw", -- " -objhelp list polyhedral objects available", -- NULL}; --\f -- /****************************************************************************** -- * Description -- * Main routine. Process command-line arguments, then bounce a bounding -- * box inside the window. Call DrawIco() to redraw the icosahedron. -- *****************************************************************************/ procedure Main (Display : X_String := ""; -- host:display Object : String := "ICO"; -- object to draw Edges : Boolean := True; -- draw obj edges Faces : Boolean := False; -- draw obj faces Geometry : X_String := ""; -- geometry to use Invert : Boolean := False; -- invert video Colors : X_String := ""; -- "red,blue,green" Dashes : S_Natural := 0; -- dash geometry Sleep : Duration := 0.0; -- pause between draws Double_Buffer : Boolean := False; -- double buffer Use_Root : Boolean := False; -- draw upon root Help_Printout : Boolean := False) is -- print obj names Fg : X_Pixel; Bg : X_Pixel; Winx : S_Short; Winy : S_Short; Winw : U_Short; Winh : U_Short; Xswa : X_Set_Window_Attributes; Xwa : X_Window_Attributes; Poly : Poly_Info_Pointer; -- the poly to draw Icox : S_Short; Icoy : S_Short; Icodeltax : S_Short; Icodeltay : S_Short; Icow : U_Short; Icoh : U_Short; Xev : X_Event; Xgcv : X_Gc_Values; Error : X_Error_String; Succ : X_Status; Env : constant X_String := X_Display_Name (Display); begin ----Process arguments: declare K : S_Natural; begin Numcolors := 0; for I in Colors'Range loop if Colors (I) = ',' then Numcolors := Numcolors + 1; end if; end loop; if Colors'Length > 0 then Colornames := new X_String_Pointer_Array (0 .. Numcolors); Numcolors := 0; K := Colors'First; for I in Colors'Range loop if Colors (I) = ',' then Colornames (Numcolors) := new X_String'(Colors (K .. I - 1)); K := I + 1; Numcolors := Numcolors + 1; elsif I = Colors'Last then Colornames (Numcolors) := new X_String'(Colors (K .. I)); Numcolors := Numcolors + 1; end if; end loop; end if; end; Dblbuf := Double_Buffer; Doedges := Edges; Dofaces := Faces; Sleepcount := Sleep; Poly := Find_Poly (Object); if Help_Printout then Give_Obj_Help; return; end if; if not Dofaces and then not Doedges then Ico_Fatal ("nothing to draw"); end if; X_Open_Display (Env, Dpy, Error); if "=" (Dpy, None_X_Display) then Ico_Fatal ("Cannot open display:" & To_String (Err (Error))); end if; if Invert then Fg := X_Black_Pixel (Dpy, X_Default_Screen (Dpy)); Bg := X_White_Pixel (Dpy, X_Default_Screen (Dpy)); else Fg := X_White_Pixel (Dpy, X_Default_Screen (Dpy)); Bg := X_Black_Pixel (Dpy, X_Default_Screen (Dpy)); end if; ----Set up window parameters, create and map window if necessary: if Use_Root then Win := X_Default_Root_Window (Dpy); Winx := 0; Winy := 0; Winw := X_Display_Width (Dpy, X_Default_Screen (Dpy)); Winh := X_Display_Height (Dpy, X_Default_Screen (Dpy)); else Winw := 700; Winh := 500; Winx := S_Short (X_Display_Width (Dpy, X_Default_Screen (Dpy)) - Winw) / 2; Winy := S_Short (X_Display_Height (Dpy, X_Default_Screen (Dpy)) - Winh) / 2; if Geometry /= "" then declare Flags : X_Parse_Geometry_Flags; begin X_Parse_Geometry (Geometry, Winx, Winy, Winw, Winh, Flags); if Flags (X_Negative) then Winx := S_Short (X_Display_Width (Dpy, X_Default_Screen (Dpy))) - Winx - S_Short (Winw); end if; if Flags (Y_Negative) then Winy := S_Short (X_Display_Height (Dpy, X_Default_Screen (Dpy))) - Winy - S_Short (Winh); end if; end; end if; Xswa.Event_Mask := X_Event_Mask' (Button_Press_Mask => True, others => False); Xswa.Background_Pixel := Bg; Xswa.Border_Pixel := Fg; Win := X_Create_Window (Dpy, X_Default_Root_Window (Dpy), Winx, Winy, Winw, Winh, 0, X_Default_Depth (Dpy, X_Default_Screen (Dpy)), Input_Output, X_Default_Visual (Dpy, X_Default_Screen (Dpy)), (Cw_Event_Mask | Cw_Back_Pixel | Cw_Border_Pixel => True, others => False), Xswa); X_Set_Text_Property (Dpy, Win, "Ico", Xa_Wm_Name); X_Map_Window (Dpy, Win); X_Get_Window_Attributes (Dpy, Win, Xwa, Succ); if Succ = Failed then Ico_Fatal ("cant get window attributes (size)"); end if; Win_Width := Xwa.Width; Win_Height := Xwa.Height; end if; ----Set up a graphics context: Gc := X_Create_Gc (Dpy, Win.Drawable, None_X_Gc_Components, None_X_Gc_Values); X_Set_Foreground (Dpy, Gc, Fg); X_Set_Background (Dpy, Gc, Bg); if Dashes /= 0 then Xgcv.Line_Style := Line_Double_Dash; Xgcv.Dashes := U_Char (Dashes); X_Change_Gc (Dpy, Gc, (Gc_Line_Style | Gc_Dash_List => True, others => False), Xgcv); end if; if Dofaces and then Numcolors >= 1 then declare T : S_Natural; Bits : Natural; begin Bits := 0; T := Numcolors; while T /= 0 loop Bits := Bits + 1; T := T / 2; end loop; Init_Dbufs (Fg, Bg, Bits); end; -- don't set the background color for I in Colornames'Range loop Set_Buf_Colname (I + 1, Colornames (I).all); end loop; if Dblbuf then -- insert new colors Set_Display_Buf (1); else Set_Display_Buf (0); end if; elsif Dblbuf or else Dofaces then Init_Dbufs (Fg, Bg, 1); end if; if Numcolors = 0 then Numcolors := 1; end if; if Dsync then X_Sync (Dpy, False); end if; ----Get the initial position, size, and speed of the bounding-box: Icow := 150; Icoh := 150; -- srandom((int) time(0) % 231); -- icoX := ((winW - icoW) * (random() and 0xFF)) >> 8; -- icoY := ((winH - icoH) * (random() and 0xFF)) >> 8; Icox := S_Short ((S_Long (Winw - Icow) * S_Long (255.0 * Ran1 (Ran_Data))) / 256); Icoy := S_Short ((S_Long (Winh - Icoh) * S_Long (255.0 * Ran1 (Ran_Data))) / 256); Icodeltax := 13; Icodeltay := 9; ----Bounce the box in the window: declare Prevx : S_Short; Prevy : S_Short; begin loop if X_Pending (Dpy) /= 0 then X_Next_Event (Dpy, Xev); if "=" (Xev.Kind, Button_Press) and then "=" (Xev.Button.Button, Button_2) then exit; end if; end if; Prevx := Icox; Prevy := Icoy; Icox := Icox + Icodeltax; if Icox < 0 or else U_Short (Icox) + Icow > Winw then Icox := Icox - (Icodeltax * 2); Icodeltax := -Icodeltax; end if; Icoy := Icoy + Icodeltay; if Icoy < 0 or else U_Short (Icoy) + Icoh > Winh then Icoy := Icoy - (Icodeltay * 2); Icodeltay := -Icodeltay; end if; Draw_Poly (Poly, Win, Gc, Icox, Icoy, Icow, Icoh, Prevx, Prevy); end loop; X_Close_Display (Dpy); end; exception when Ico_Fatal_Error => null; end Main; --\f function Tl (S : String; L : Natural) return String is R : String (1 .. L) := (others => ' '); begin if S'Length < L then R (1 .. S'Length) := S; else R := S (S'First .. S'First - 1 + L); end if; return R; end Tl; --\f procedure Give_Obj_Help is begin Text_Io.Put_Line ("Name Short Name #Vert. #Edges #Faces Dual"); for I in Polys'Range loop Text_Io.Put (Tl (Polys (I).Long_Name.all, 16)); Text_Io.Put (Tl (Polys (I).Short_Name.all, 12)); S_Long_Io.Put (S_Long (Polys (I).Num_Verts), 6); S_Long_Io.Put (S_Long (Polys (I).Num_Edges), 8); S_Long_Io.Put (S_Long (Polys (I).Num_Faces), 8); Text_Io.Put_Line (Polys (I).Dual.all); end loop; end Give_Obj_Help; --\f function Find_Poly (Name : String) return Poly_Info_Pointer is function Equal (A, B : String) return Boolean is Ac : Character; Bc : Character; begin if A'Length /= B'Length then return False; end if; for I in Natural range 0 .. A'Length - 1 loop Ac := A (A'First + I); Bc := B (B'First + I); if Ac /= Bc then if Ac in 'a' .. 'z' then Ac := Character'Val (Character'Pos (Ac) - (Character'Pos ('a') - Character'Pos ('A'))); end if; if Bc in 'a' .. 'z' then Bc := Character'Val (Character'Pos (Bc) - (Character'Pos ('a') - Character'Pos ('A'))); end if; if Ac /= Bc then return False; end if; end if; end loop; return True; end Equal; begin for I in Polys'Range loop if Equal (Polys (I).Long_Name.all, Name) or else Equal (Polys (I).Short_Name.all, Name) then return Polys (I); end if; end loop; Ico_Fatal ("can't find object " & Name); end Find_Poly; --\f procedure Ico_Clear_Area (X : S_Short; Y : S_Short; W : U_Short; H : U_Short) is begin if Dblbuf or else Dofaces then X_Set_Foreground (Dpy, Gc, Dbpair.Bufs (Dbpair.Draw_Buf).Pixels (0)); -- use background as foreground color for fill X_Fill_Rectangle (Dpy, Win.Drawable, Gc, X, Y, W, H); else X_Clear_Area (Dpy, Win, X, Y, W, H, False); end if; end Ico_Clear_Area; --\f ------------------------------------------------------------------------------ -- Description -- Undraw previous polyhedron (by erasing its bounding box). -- Rotate and draw the new polyhedron. -- -- Input -- poly the polyhedron to draw -- win window on which to draw -- gc X11 graphics context to be used for drawing -- icoX, icoY position of upper left of bounding-box -- icoW, icoH size of bounding-box -- prevX, prevY position of previous bounding-box ------------------------------------------------------------------------------ procedure Draw_Poly (Poly : Poly_Info_Pointer; Win : X_Window; Gc : X_Gc; Icox : S_Short; Icoy : S_Short; Icow : U_Short; Icoh : U_Short; Prevx : S_Short; Prevy : S_Short) is V : Point_3d_List := Poly.V; Nv : S_Natural := Poly.Num_Verts; F : S_Natural_List := Poly.F; Nf : S_Natural := Poly.Num_Faces; P0 : S_Natural; P1 : S_Natural; Pv2 : S_Natural; Pe : S_Natural; Pxv : S_Natural; V2 : X_Point_Array (0 .. Max_Nv - 1); Edges : X_Segment_Array (0 .. Max_Edges - 1); Pf : S_Natural; Facecolor : S_Natural; K : S_Natural; Pcount : S_Natural; Pxvz : Float; Ppts : X_Point_Array (0 .. Max_Edges_Per_Poly - 1); begin ----Set up points, transforms, etc.: if not Initialized then declare R1 : Transform_3d; R2 : Transform_3d; begin Format_Rotate_Mat ('x', 5.0 * 3.1416 / 180.0, R1); Format_Rotate_Mat ('y', 5.0 * 3.1416 / 180.0, R2); Concat_Mat (R1, R2, Xform); Xv (False) (0 .. Nv - 1) := V.all; Buffer := False; Wo2 := Float (Icow) / 2.0; Ho2 := Float (Icoh) / 2.0; Initialized := True; end; end if; ----Switch double-buffer and rotate vertices: Buffer := not Buffer; Partial_Non_Hom_Transform (Nv, Xform, Xv (not Buffer), Xv (Buffer)); ----Convert 3D coordinates to 2D window coordinates: Pxv := Xv (Buffer)'First; Pv2 := V2'First; for I in reverse 0 .. Nv - 1 loop V2 (Pv2).X := S_Short ((Xv (Buffer) (Pxv).X + 1.0) * Wo2) + Icox; V2 (Pv2).Y := S_Short ((Xv (Buffer) (Pxv).Y + 1.0) * Ho2) + Icoy; Pxv := Pxv + 1; Pv2 := Pv2 + 1; end loop; ----Accumulate edges to be drawn, eliminating duplicates for speed: Pxv := Xv (Buffer)'First; Pv2 := V2'First; Pf := F'First; Pe := Edges'First; --geb This is unbelieveably slow. R1000 compiler is stupid. Drawn := (others => (others => 0)); Drawn := Zero; if Dblbuf then Set_Draw_Buf (Dbpair.Dbuf_Num); -- switch drawing buffers if double buffered end if; if Dofaces then -- for faces, need to clear before FillPoly if Dblbuf then Ico_Clear_Area (Dbpair.Bufs (Dbpair.Draw_Buf).Prev_X, Dbpair.Bufs (Dbpair.Draw_Buf).Prev_Y, Icow + 1, Icoh + 1); end if; Ico_Clear_Area (Prevx, Prevy, Icow + 1, Icoh + 1); end if; if Dsync then X_Sync (Dpy, False); end if; for I in reverse 0 .. Nf - 1 loop Pcount := F (Pf); -- number of edges for this face Pf := Pf + 1; Pxvz := 0.0; for J in 0 .. Pcount - 1 loop P0 := F (Pf + J); Pxvz := Pxvz + Xv (Buffer) (Pxv + P0).Z; end loop; -- If facet faces away from viewer, don't consider it: if Pxvz < 0.0 then goto Continue; end if; if Dofaces then if Numcolors /= 0 then Facecolor := I rem Numcolors + 1; else Facecolor := 1; end if; X_Set_Foreground (Dpy, Gc, Dbpair.Bufs (Dbpair.Draw_Buf).Pixels (Facecolor)); for J in 0 .. Pcount - 1 loop P0 := F (Pf + J); Ppts (J).X := V2 (Pv2 + P0).X; Ppts (J).Y := V2 (Pv2 + P0).Y; end loop; X_Fill_Polygon (Dpy, Win.Drawable, Gc, Ppts (0 .. Pcount - 1), Convex, Coord_Mode_Origin); end if; if Doedges then for J in 0 .. Pcount - 1 loop if J < Pcount - 1 then K := J + 1; else K := 0; end if; P0 := F (Pf + J); P1 := F (Pf + K); if (Drawn (P0, P1) = 0) then Drawn (P0, P1) := 1; Drawn (P1, P0) := 1; Edges (Pe).X1 := V2 (Pv2 + P0).X; Edges (Pe).Y1 := V2 (Pv2 + P0).Y; Edges (Pe).X2 := V2 (Pv2 + P1).X; Edges (Pe).Y2 := V2 (Pv2 + P1).Y; Pe := Pe + 1; end if; end loop; end if; <<Continue>> null; Pf := Pf + Pcount; end loop; ----Erase previous, draw current icosahedrons; sync for smoothness. if Doedges then if Dofaces then X_Set_Foreground (Dpy, Gc, Dbpair.Bufs (Dbpair.Draw_Buf).Pixels (0)); -- use background as foreground color else if Dblbuf then Ico_Clear_Area (Dbpair.Bufs (Dbpair.Draw_Buf).Prev_X, Dbpair.Bufs (Dbpair.Draw_Buf).Prev_Y, Icow + 1, Icoh + 1); end if; Ico_Clear_Area (Prevx, Prevy, Icow + 1, Icoh + 1); if Dblbuf or else Dofaces then X_Set_Foreground (Dpy, Gc, Dbpair.Bufs (Dbpair.Draw_Buf).Pixels (Dbpair.Pixels_Per_Buf - 1)); end if; end if; X_Draw_Segments (Dpy, Win.Drawable, Gc, Edges (0 .. Pe - 1)); end if; if Dsync then X_Sync (Dpy, False); end if; if Dblbuf then Dbpair.Bufs (Dbpair.Draw_Buf).Prev_X := Icox; Dbpair.Bufs (Dbpair.Draw_Buf).Prev_Y := Icoy; Set_Display_Buf (Dbpair.Dbuf_Num); end if; -- X_Sync (Dpy, False); if Dblbuf then Dbpair.Dbuf_Num := 1 - Dbpair.Dbuf_Num; end if; if Sleepcount /= 0.0 then delay Sleepcount; end if; end Draw_Poly; --\f procedure Init_Dbufs (Fg : X_Pixel; Bg : X_Pixel; Planes_Per_Buf : Natural) is K : S_Natural; M : S_Natural; Q : S_Natural; Succ : X_Status; begin Dbpair.Planes_Per_Buf := S_Natural (Planes_Per_Buf); Dbpair.Pixels_Per_Buf := 2 ** Planes_Per_Buf; if Dblbuf then Dbpair.Total_Planes := S_Long (2 * Planes_Per_Buf); else Dbpair.Total_Planes := S_Long (Planes_Per_Buf); end if; Dbpair.Total_Pixels := 2 ** Natural (Dbpair.Total_Planes); Dbpair.Plane_Masks := new X_Plane_Mask_Array (0 .. Dbpair.Total_Planes - 1); Dbpair.Dbuf_Num := 0; if Dblbuf then Q := 2; else Q := 1; end if; for I in 0 .. Q - 1 loop declare B : Dbuf_Info renames Dbpair.Bufs (I); begin B.Plane_Masks := Dbpair.Plane_Masks'First + (I * S_Long (Planes_Per_Buf)); B.Colors := new X_Color_Array (0 .. Dbpair.Total_Pixels - 1); B.Pixels := new X_Pixel_Array (0 .. Dbpair.Pixels_Per_Buf - 1); end; end loop; Cmap := X_Default_Colormap (Dpy, X_Default_Screen (Dpy)); if "=" (Cmap, None_X_Colormap) then Ico_Fatal ("can't get default colormap"); end if; X_Alloc_Color_Cells (Dpy, Cmap, False, Dbpair.Plane_Masks.all, Dbpair.Pixels (Dbpair.Pixels'First .. Dbpair.Pixels'First), Succ); -- allocate color planes */ if Succ = Failed then Ico_Fatal ("can't allocate color planes"); end if; Fg_Color.Pixel := Fg; Bg_Color.Pixel := Bg; X_Query_Color (Dpy, Cmap, Fg_Color); X_Query_Color (Dpy, Cmap, Bg_Color); Set_Buf_Color (0, Bg_Color); Set_Buf_Color (1, Fg_Color); for I in 0 .. Q - 1 loop declare B : Dbuf_Info renames Dbpair.Bufs (I); J : S_Natural; Jj : S_Natural; begin --if dblbuf then -- otherb := dbpair.bufs+(1-i); --end if; if Dblbuf then Q := Dbpair.Pixels_Per_Buf; else Q := 1; end if; for J0 in 0 .. Q - 1 loop for J1 in 0 .. Dbpair.Pixels_Per_Buf - 1 loop J := S_Natural (J0 * 2 ** Natural (Dbpair.Planes_Per_Buf)) or S_Natural (J1); if I = 0 then Jj := J; else Jj := S_Natural (J1 * 2 ** Natural (Dbpair.Planes_Per_Buf)) or S_Natural (J0); end if; B.Colors (Jj).Pixel := Dbpair.Pixels (0); K := 0; M := J; while M /= 0 loop if M rem 2 /= 0 then B.Colors (Jj).Pixel := "or" (B.Colors (Jj).Pixel, X_Pixel (Dbpair.Plane_Masks (K))); end if; K := K + 1; M := M / 2; end loop; B.Colors (Jj).Flags := X_Color_Flags'(Do_Red | Do_Green | Do_Blue => True, others => False); end loop; end loop; B.Prev_X := 0; B.Prev_Y := 0; B.En_Plane_Mask := 0; for J in 0 .. Planes_Per_Buf - 1 loop B.En_Plane_Mask := "or" (B.En_Plane_Mask, Dbpair.Plane_Masks (B.Plane_Masks + S_Long (J))); end loop; for J in 0 .. Dbpair.Pixels_Per_Buf - 1 loop B.Pixels (J) := Dbpair.Pixels (0); K := 0; M := J; while M /= 0 loop if M rem 2 /= 0 then B.Pixels (J) := "or" (B.Pixels (J), X_Pixel (Dbpair.Plane_Masks (B.Plane_Masks + K))); end if; K := K + 1; M := M / 2; end loop; end loop; end; end loop; Set_Draw_Buf (0); X_Set_Background (Dpy, Gc, Dbpair.Bufs (0).Pixels (0)); X_Set_Plane_Mask (Dpy, Gc, All_Planes); Ico_Clear_Area (0, 0, Win_Width, Win_Height); -- clear entire window delay Isleepcount; -- geb? /*** doesn't work without this!!! */ X_Sync (Dpy, False); if Dblbuf then Set_Display_Buf (1); else Set_Display_Buf (0); end if; end Init_Dbufs; --\f procedure Set_Buf_Colname (N : S_Natural; Colname : X_String) is Succ : X_Status; Dcolor : X_Color; Color : X_Color; begin X_Lookup_Color (Dpy, Cmap, Colname, Dcolor, Color, Succ); if Succ = Failed then -- no such color Ico_Fatal ("no such color " & To_String (Colname)); end if; Set_Buf_Color (N, Color); end Set_Buf_Colname; --\f procedure Set_Buf_Color (N : S_Natural; -- color index Color : X_Color) is -- color to set Cx : S_Natural; Pix : X_Pixel; Q : S_Natural; begin if Dblbuf then Q := 2; else Q := 1; end if; for I in 0 .. Q - 1 loop declare B : Dbuf_Info renames Dbpair.Bufs (I); begin if Dblbuf then Q := Dbpair.Pixels_Per_Buf; else Q := 1; end if; for J in 0 .. Q - 1 loop Cx := N + J * Dbpair.Pixels_Per_Buf; Pix := B.Colors (Cx).Pixel; B.Colors (Cx) := Color; B.Colors (Cx).Pixel := Pix; B.Colors (Cx).Flags := X_Color_Flags'(Do_Red | Do_Green | Do_Blue => True, others => False); end loop; end; end loop; end Set_Buf_Color; --\f procedure Set_Draw_Buf (N : S_Natural) is Xgcv : X_Gc_Values; Mask : X_Gc_Components; begin Dbpair.Draw_Buf := Dbpair.Bufs'First + N; Xgcv.Plane_Mask := Dbpair.Bufs (Dbpair.Draw_Buf).En_Plane_Mask; Xgcv.Foreground := Dbpair.Bufs (Dbpair.Draw_Buf).Pixels (Dbpair.Pixels_Per_Buf - 1); Xgcv.Background := Dbpair.Bufs (Dbpair.Draw_Buf).Pixels (0); Mask := X_Gc_Components' (Gc_Foreground | Gc_Background => True, others => False); if Dblbuf then Mask (Gc_Plane_Mask) := True; end if; X_Change_Gc (Dpy, Gc, Mask, Xgcv); end Set_Draw_Buf; --\f procedure Set_Display_Buf (N : S_Natural) is begin Dbpair.Dpy_Buf := Dbpair.Bufs'First + N; X_Store_Colors (Dpy, Cmap, Dbpair.Bufs (Dbpair.Dpy_Buf).Colors.all); end Set_Display_Buf; --\f procedure Ico_Fatal (Fmt : String) is begin Text_Io.Put_Line ("ico: " & Fmt); raise Ico_Fatal_Error; end Ico_Fatal; --\f ------------------------------------------------------------------------------ -- Description -- Concatenate two 4-by-4 transformation matrices. -- -- Input -- l multiplicand (left operand) -- r multiplier (right operand) -- -- Output -- *m Result matrix ------------------------------------------------------------------------------ procedure Concat_Mat (L : Transform_3d; R : Transform_3d; M : in out Transform_3d) is begin for I in 0 .. 3 loop for J in 0 .. 3 loop M (I, J) := L (I, 0) * R (0, J) + L (I, 1) * R (1, J) + L (I, 2) * R (2, J) + L (I, 3) * R (3, J); end loop; end loop; end Concat_Mat; --\f ------------------------------------------------------------------------------ -- Description -- Format a matrix that will perform a rotation transformation -- about the specified axis. The rotation angle is measured -- counterclockwise about the specified axis when looking -- at the origin from the positive axis. -- -- Input -- axis Axis ('x', 'y', 'z') about which to perform rotation -- angle Angle (in radians) of rotation -- A Pointer to rotation matrix -- -- Output -- *m Formatted rotation matrix ------------------------------------------------------------------------------ procedure Format_Rotate_Mat (Axis : Character; Angle : Float; M : in out Transform_3d) is S : Float; C : Float; begin Ident_Mat (M); S := Trig.Sin (Angle); C := Trig.Cos (Angle); case Axis is when 'x' => M (1, 1) := C; M (2, 2) := C; M (1, 2) := S; M (2, 1) := -S; when 'y' => M (0, 0) := C; M (2, 2) := C; M (2, 0) := S; M (0, 2) := -S; when 'z' => M (0, 0) := C; M (1, 1) := C; M (0, 1) := S; M (1, 0) := -S; when others => raise Program_Error; end case; end Format_Rotate_Mat; --\f ------------------------------------------------------------------------------ -- Description -- Format a 4x4 identity matrix. -- -- Output -- *m Formatted identity matrix ------------------------------------------------------------------------------ procedure Ident_Mat (M : in out Transform_3d) is begin for I in reverse 0 .. 3 loop for J in reverse 0 .. 3 loop M (I, J) := 0.0; end loop; M (I, I) := 1.0; end loop; end Ident_Mat; --\f ------------------------------------------------------------------------------ -- Description -- Perform a partial transform on non-homogeneous points. -- Given an array of non-homogeneous (3-coordinate) input points, -- this routine multiplies them by the 3-by-3 upper left submatrix -- of a standard 4-by-4 transform matrix. The resulting non-homogeneous -- points are returned. -- -- Input -- n number of points to transform -- m 4-by-4 transform matrix -- in array of non-homogeneous input points -- -- Output -- *out array of transformed non-homogeneous output points ------------------------------------------------------------------------------ procedure Partial_Non_Hom_Transform (N : S_Natural; M : Transform_3d; Inn : Point_3d_Array; Outt : in out Point_3d_Array) is Ini : S_Natural := Inn'First; Outi : S_Natural := Outt'First; begin for I in 1 .. N loop Outt (Outi).X := Inn (Ini).X * M (0, 0) + Inn (Ini).Y * M (1, 0) + Inn (Ini).Z * M (2, 0); Outt (Outi).Y := Inn (Ini).X * M (0, 1) + Inn (Ini).Y * M (1, 1) + Inn (Ini).Z * M (2, 1); Outt (Outi).Z := Inn (Ini).X * M (0, 2) + Inn (Ini).Y * M (1, 2) + Inn (Ini).Z * M (2, 2); Ini := Ini + 1; Outi := Outi + 1; end loop; end Partial_Non_Hom_Transform; --\f begin declare Clk : Calendar.Day_Duration := Calendar.Seconds (Calendar.Clock); I : Natural; begin I := Natural (Clk / Duration (100.0)); Clk := Calendar.Day_Duration (Clk - Duration (Duration (I) * Duration (100.00))); ----Clk is now in the 0..99.9999 range. Ran_Data := Ran1_Initialize (S_Natural (Float (Clk) * Float (Natural'Last / 101))); end; end Ico_Main;