home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 207.lha / Evo / evo.c < prev    next >
C/C++ Source or Header  |  1988-12-28  |  21KB  |  721 lines

  1.  
  2. #include "INCLUDE:Lattice/math.h"
  3. #include "INCLUDE:Lattice/stdio.h"
  4. #include "INCLUDE:exec/types.h"
  5. #include "INCLUDE:graphics/gfx.h"
  6. #include "INCLUDE:graphics/gfxmacros.h"
  7. #include "INCLUDE:exec/exec.h"
  8. #include "INCLUDE:exec/execbase.h"
  9. #include "INCLUDE:graphics/view.h"
  10. #include "INCLUDE:graphics/gfxbase.h"
  11. #include "INCLUDE:exec/libraries.h"
  12. #include "INCLUDE:intuition/intuition.h"
  13. #include "INCLUDE:graphics/text.h"
  14.  
  15. struct  NewScreen  ns;
  16. struct  NewWindow  nw;
  17.  
  18. struct  Screen     *evo_screen;
  19. struct  Window     *evo_window, *map_window, *text_window;
  20.  
  21. struct  RastPort   *rp, *rp2;
  22. struct  ViewPort   *vp;
  23.  
  24. struct  IntuiMessage  *message;
  25.  
  26. struct  TextAttr       Ruby_Eight;
  27. struct  TextFont       *fontptr;
  28.  
  29. struct  GfxBase       *GfxBase;
  30. struct  IntuitionBase *IntuitionBase;
  31. struct  Library       *DiskfontBase;
  32.  
  33. SHORT   hominid;
  34. SHORT   hominid_index[621];
  35.  
  36. int     i, j, x, y, oldx, class, code, rc, color, parity;
  37. int     delta_t, delta_x, delta_y, s, fossil_index;
  38. int     point, selected_box;
  39. BOOL    button_is_down, first_pass;
  40.  
  41. UBYTE   profile[ 621 ][ 52 ][ 2 ];
  42.  
  43. int     SetUpEvographics(), DrawMap(), DisplayText();
  44.  
  45. #include "evo_species.include"
  46. #include "evo_data.include"
  47. #include "evo_africa.include"
  48. #include "evo_text.include"
  49.  
  50. /*---------------------------------------*/
  51. /*                                       */
  52. /*             //  Evo  //               */
  53. /*                                       */
  54. /*    A human evolution demonstration    */
  55. /*        program for the Amiga          */
  56. /*                                       */
  57. /*            Steve Bonner               */
  58. /*            August 1987                */
  59. /*                                       */
  60. /*---------------------------------------*/
  61.  
  62. main()
  63. {
  64.   register int k;
  65.  
  66. GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
  67. IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
  68.  
  69. if( (GfxBase == NULL) || (IntuitionBase == NULL)) exit();
  70.  
  71. DiskfontBase = OpenLibrary("diskfont.library",0);
  72. if ( DiskfontBase == NULL ) exit();
  73.  
  74.  
  75. SetUpEvographics();
  76.  
  77. SetDrMd( rp, JAM2 );
  78. SetAPen( rp, 2 );
  79.  
  80. RectFill( rp, 45, 20, 295, 120 );
  81. Move( rp, 110, 55 );
  82.  
  83. SetAPen( rp, 7 );
  84. SetBPen( rp, 2 );
  85. Text( rp, "(please wait)", 13 );
  86.  
  87. SetAPen( rp, 2 );
  88. SetBPen( rp, 0 );
  89.  
  90. Move( rp,  20, 140 );
  91. Draw( rp, 620, 140 );
  92.  
  93. for ( i = 0; i <= 20; i++)        {
  94.   Move( rp, gradation[i], 138 );
  95.   Draw( rp, gradation[i], 142 );  }
  96.  
  97. Move( rp, 9, 137 );
  98. Text( rp,
  99.   "20            10            5   4   3      2        1  ", 55 );
  100. Move( rp, 9, 152 );
  101. Text( rp,
  102.   "        Miocene         Pliocene            Pleistocene", 55 );
  103.  
  104. Move( rp, 325, 45 )    ;
  105. Text( rp, "Genus       ", 12 );
  106. Move( rp, 325, 60 )    ;
  107. Text( rp, "Species     ", 12 );
  108. Move( rp, 325, 75 )    ;
  109. Text( rp, "Subspecies  ", 12 );
  110. Move( rp, 325, 90 )    ;
  111. Text( rp, "Mill yrs ago", 12 );
  112.  
  113. Move( rp, 435, 45 );
  114. Text( rp, ":",  1 );
  115. Move( rp, 435, 60 );
  116. Text( rp, ":",  1 );
  117. Move( rp, 435, 75 );
  118. Text( rp, ":",  1 );
  119. Move( rp, 435, 90 );
  120. Text( rp, ":",  1 );
  121.  
  122.  
  123. /* Draw the boxes to surround user options:  */
  124. for ( k = 0; k < 5; k++)           {
  125.   SetAPen( rp, 3 );
  126.   RectFill( rp, 20 + k * 122, 172, 132 + k * 122, 192 );
  127.   SetAPen( rp, 6 );
  128.   Move( rp,  20 + k * 122 , 172 );
  129.   Draw( rp, 132 + k * 122 , 172 );
  130.   Draw( rp, 132 + k * 122 , 192 );
  131.   Draw( rp,  20 + k * 122 , 192 );
  132.   Draw( rp,  20 + k * 122 , 172 ); }
  133.  
  134. SetDrMd( rp, JAM1 );
  135. Move( rp, 20, 185 );
  136. /*  Here are the various options:  */
  137. Text( rp,
  138.    "    Help         Text          Map        Glossary      Notes",
  139.    61 );
  140.  
  141. SetAPen( rp, 2 );
  142. SetDrMd( rp, JAM2 );
  143.  
  144. x = 0;
  145. y = 1;
  146.  
  147. /*  The cranium for each hominid species consists of 52 points    */
  148. /*  which define its outline.  Here we are copying the outlines   */
  149. /*  of the nine known hominids into our working array, 'profile'  */
  150. for ( i = 0; i <= 51; i++) {
  151.   j = 2*i;
  152.   k = j+1;
  153.  
  154.   profile[  20 ][ i ][ x ] = proconsul_profile[ j ];
  155.   profile[  20 ][ i ][ y ] = proconsul_profile[ k ];
  156.   profile[ 147 ][ i ][ x ] = kenyapith_profile[ j ];
  157.   profile[ 147 ][ i ][ y ] = kenyapith_profile[ k ];
  158.   profile[ 333 ][ i ][ x ] = afarensis_profile[ j ];
  159.   profile[ 333 ][ i ][ y ] = afarensis_profile[ k ];
  160.   profile[ 360 ][ i ][ x ] = africanus_profile[ j ];
  161.   profile[ 360 ][ i ][ y ] = africanus_profile[ k ];
  162.   profile[ 403 ][ i ][ x ] = habilis_profile  [ j ];
  163.   profile[ 403 ][ i ][ y ] = habilis_profile  [ k ];
  164.   profile[ 439 ][ i ][ x ] = erectus_profile  [ j ];
  165.   profile[ 439 ][ i ][ y ] = erectus_profile  [ k ];
  166.   profile[ 554 ][ i ][ x ] = esapiens_profile [ j ];
  167.   profile[ 554 ][ i ][ y ] = esapiens_profile [ k ];
  168.   profile[ 611 ][ i ][ x ] = neander_profile  [ j ];
  169.   profile[ 611 ][ i ][ y ] = neander_profile  [ k ];
  170.   profile[ 620 ][ i ][ x ] = msapiens_profile [ j ];
  171.   profile[ 620 ][ i ][ y ] = msapiens_profile [ k ];  }
  172.  
  173.  
  174. /*  Interpolate between known hominid forms:   */
  175. for ( i = PROCONSUL; i <= NEANDER; i++)  {
  176.   delta_t = fossil_dates[i+1] - fossil_dates[i];
  177.   fossil_index = fossil_dates[i];
  178.  
  179.   Forbid();
  180.  
  181.   /* Now consider each point along the profile: */
  182.   for ( j = 0; j <= 51; j++ ) {
  183.  
  184.     delta_x = profile[ fossil_dates[i+1] ][ j ][ x ] -
  185.               profile[ fossil_index      ][ j ][ x ] ;
  186.     delta_y = profile[ fossil_dates[i+1] ][ j ][ y ] -
  187.               profile[ fossil_index      ][ j ][ y ] ;
  188.     s = 1;
  189.  
  190.     /*  Here we do the linear interpolation.                         */
  191.     /*  (I interpolate on the logarithmic scale, since it's easier.) */
  192.     for ( k = fossil_dates[i]+1; k < fossil_dates[i+1]; k++)        {
  193.       profile[ k ][ j ][ x ] = profile[ fossil_index ][ j ][ x ] +
  194.               s * delta_x / delta_t;
  195.       profile[ k ][ j ][ y ] = profile[ fossil_index ][ j ][ y ] +
  196.               s * delta_y / delta_t;
  197.       s++;
  198.                                                                     }
  199.                            }  /*  j  */
  200.     /* Let's give our disk drive a chance to catch up: */
  201.     Permit();
  202.                            }  /*  i  */
  203.  
  204.  
  205.  
  206. button_is_down = FALSE;
  207.  
  208. oldx = 403;
  209. SetAPen( rp, 1 );
  210. WritePixel( rp, oldx, 140 );
  211. hominid = 4;
  212.  
  213. Move( rp, 460, 45 );
  214. Text( rp, genera[ hominid ], 18 );
  215. Move( rp, 460, 60 );
  216. Text( rp, species[ hominid ], 18 );
  217. Move( rp, 460, 90 );
  218. Text( rp, yearstring[oldx], 6 );
  219.  
  220.  
  221. /*  Hominid_divisions allows us to rapidly map an x-coordinate    */
  222. /*  into its corresponding hominid form (an integer from 0 to 8)  */
  223. hominid = 8;
  224. for (i = 620; i >= 20; i--)   {
  225.   if ( i < hominid_divisions[ hominid ] ) hominid--;
  226.   hominid_index[i] = hominid; }
  227.  
  228. color = 8;
  229.  
  230. hominid = 4;
  231. first_pass = TRUE;
  232.  
  233. Forbid();
  234.  
  235. while ( 1 == 1) {
  236.  
  237.   if (first_pass == FALSE )    {
  238.     WaitPort( evo_window -> UserPort );
  239.     message = GetMsg( evo_window -> UserPort );
  240.  
  241.     class = message -> Class;
  242.     code  = message -> Code;
  243.     x     = message -> MouseX;
  244.     y     = message -> MouseY;
  245.  
  246.     ReplyMsg( message );       }
  247.  
  248.   else                         {
  249.     class = 0;
  250.     code  = SELECTUP;
  251.     x     = oldx;
  252.     y     = 140;
  253.     first_pass = FALSE;        }
  254.  
  255.  
  256.   if ( class == CLOSEWINDOW )   {
  257.     CloseWindow( evo_window );
  258.     CloseScreen( evo_screen );
  259.     exit();                     }
  260.  
  261.   if ( code == SELECTDOWN ) {
  262.  
  263.     point = ReadPixel( rp, x, y );
  264.  
  265.     /*  Is our current pixel a 'user-option' color?. . .  */
  266.     if ( (point == 3) || (point == 6) ) {
  267.       selected_box = (x - 10)/122;
  268.  
  269.       if (selected_box == 2)
  270.         DrawMap();
  271.       else
  272.         DisplayText();
  273.  
  274.       goto NoSkull;                     }
  275.  
  276.     button_is_down = TRUE;
  277.     color = 8;              }
  278.  
  279.   if ( code == SELECTUP   ) button_is_down = FALSE;
  280.  
  281.   if ( (button_is_down) || (code == SELECTUP) )   {
  282.  
  283.     if ((x >= 20) && (x <= 620)) {
  284.     SetAPen( rp, 2 );
  285.     WritePixel( rp, oldx, 140 );
  286.     SetAPen( rp, 1 );
  287.     WritePixel( rp,    x, 140 );
  288.     oldx = x;
  289.  
  290.     /*  If the species has changed, update the labels:  */
  291.     if ( hominid != hominid_index[x] )       {
  292.       hominid = hominid_index[x];
  293.  
  294.       Move( rp, 460, 45 );
  295.       Text( rp, genera[ hominid ], 18 );
  296.       Move( rp, 460, 60 );
  297.       Text( rp, species[ hominid ], 18 );
  298.       Move( rp, 460, 75 );
  299.       Text( rp, subspecies[ hominid ], 18 ); }
  300.  
  301.     Move( rp, 460, 90 );
  302.     Text( rp, yearstring[x], 6 );
  303.  
  304.     if ( code == SELECTUP )              {
  305.       color = 1;
  306.       SetAPen( rp, 2 );
  307.       RectFill( rp, 45, 20, 295, 120 );  }
  308.     else                                 {
  309.       color++;
  310.       color%=16;
  311.       if (color < 8) color += 8;         }
  312.  
  313.     parity = x % 2;
  314.  
  315.     /*  we cheat a little to speed things up:   */
  316.     if ((code != SELECTUP) && (code != SELECTDOWN) && (parity == 1)) {
  317.       goto FastForward; }
  318.  
  319.     SetAPen( rp, color );
  320.  
  321.     Move( rp, profile[ x ][ 0 ][ 0 ], profile[ x ][ 0 ][ 1 ] );
  322.  
  323.     /* Draw the outside of the cranium: */
  324.     Disable();
  325.     /* OK, let's see if it can keep up. . .       */
  326.     for ( k = 1; k < 27; k++ ) {
  327.       Draw( rp, profile[x][k][0], profile[x][k][1] ); }
  328.     Enable();
  329.  
  330.     Draw( rp, profile[x][0][0], profile[x][0][1] );
  331.  
  332.     /* Now for the lower cheekbone */
  333.     Move( rp, profile[x][27][0], profile[x][27][1] );
  334.     for ( k=28; k < 30; k++) Draw( rp, profile[x][k][0], profile[x][k][1] );
  335.  
  336.     /* Now the upper cheekbone:    */
  337.     Move( rp, profile[x][30][0], profile[x][30][1] );
  338.     for ( k=31; k < 39; k++) Draw( rp, profile[x][k][0], profile[x][k][1] );
  339.  
  340.     /* Now draw around the eye:    */
  341.     Move( rp, profile[x][39][0], profile[x][39][1] );
  342.     for ( k=40; k < 47; k++) Draw( rp, profile[x][k][0], profile[x][k][1] );
  343.     Draw( rp, profile[x][39][0], profile[x][39][1] );
  344.  
  345.     /* Now draw around the ear:    */
  346.     Move( rp, profile[x][47][0], profile[x][47][1] );
  347.     for ( k=48; k < 52; k++) Draw( rp, profile[x][k][0], profile[x][k][1] );
  348.     Draw( rp, profile[x][47][0], profile[x][47][1] );
  349.  
  350.     FastForward:
  351.                       }    /*   x in range 20..620   */
  352.  
  353.                       }    /*     Button is down     */
  354.     NoSkull: 
  355.                       }    /*       While End        */
  356.  
  357.  
  358. }  /* main */
  359.  
  360. /*--------------------------------------------*/
  361.  
  362. SetUpEvographics()
  363. {
  364.   int  font_avail;
  365.   BOOL response;
  366.   struct IntuiText nofont, stop;
  367.   
  368.   /*  Use ruby font in 80-column size:  */
  369.   Ruby_Eight.ta_Name = "ruby.font";
  370.   Ruby_Eight.ta_YSize = 8;
  371.   Ruby_Eight.ta_Style = 0;
  372.   Ruby_Eight.ta_Flags = 0;
  373.  
  374.   
  375.  
  376.   font_avail = OpenDiskFont(&Ruby_Eight);
  377.  
  378.  
  379.   /*  If the ruby font is not available, display a requester and exit:  */
  380.   if ( font_avail == FALSE ) {
  381.     nofont.FrontPen  = 3;
  382.     nofont.BackPen   = 2;
  383.     nofont.DrawMode  = JAM1;
  384.     nofont.LeftEdge  = 10;
  385.     nofont.TopEdge   =  5;
  386.     nofont.ITextFont = NULL;
  387.     nofont.IText     = "Ruby font not in font directory.\0";
  388.     nofont.NextText  = NULL;
  389.  
  390.     stop.FrontPen  =  2;
  391.     stop.BackPen   =  3;
  392.     stop.DrawMode  =  JAM1;
  393.     stop.LeftEdge  =  4;
  394.     stop.TopEdge   =  3;
  395.     stop.ITextFont = NULL;
  396.     stop.IText     = "exit\0";
  397.     stop.NextText  = NULL;
  398.  
  399.     response = AutoRequest(NULL, &nofont, NULL, &stop, 0,0,420,60);
  400.     exit();         }
  401.  
  402.   /*  Define properties new screen is to have:        */
  403.   ns.LeftEdge     =   0;
  404.   ns.TopEdge      =   0;
  405.   ns.Width        = 640;
  406.   ns.Height       = 200;
  407.   ns.Depth        =   4;
  408.   ns.DetailPen    =   1;
  409.   ns.BlockPen     =   2;
  410.   ns.ViewModes    = HIRES;
  411.   ns.Type         = CUSTOMSCREEN;
  412.   ns.Font         = &Ruby_Eight;
  413.   ns.DefaultTitle = "    \0";
  414.   ns.Gadgets      = NULL;
  415.   ns.CustomBitMap = NULL;
  416.  
  417.   evo_screen = OpenScreen( &ns );
  418.   if ( evo_screen == NULL ) exit();
  419.  
  420.   /*   Describe new window:      */
  421.   nw.LeftEdge    =    0;
  422.   nw.TopEdge     =    0;
  423.   nw.Width       =  640;
  424.   nw.Height      =  200;
  425.   nw.DetailPen   =   -1;
  426.   nw.BlockPen    =   -1;
  427.   nw.IDCMPFlags  = CLOSEWINDOW   | MOUSEBUTTONS  | MOUSEMOVE;
  428.   nw.Type        = CUSTOMSCREEN;
  429.   nw.Flags       = WINDOWCLOSE   | SMART_REFRESH | ACTIVATE |
  430.                    NOCAREREFRESH | REPORTMOUSE   ;
  431.   nw.FirstGadget = NULL;
  432.   nw.CheckMark   = NULL;
  433.   nw.Screen      = evo_screen;
  434.   nw.Title       = " Evo ";
  435.   nw.BitMap      = NULL;
  436.   nw.MinWidth    =    0;
  437.   nw.MinHeight   =    0;
  438.   nw.MaxWidth    =    0;
  439.   nw.MaxHeight   =    0;
  440.  
  441.   evo_window = OpenWindow( &nw );
  442.   if (evo_window == NULL)    exit();
  443.  
  444.   WindowToFront(evo_window);
  445.  
  446.   rp = evo_window  -> RPort;
  447.   vp = &evo_screen -> ViewPort;
  448.  
  449.   SetRGB4( vp,  0,  7,  2,  3 );     /*  plum    */
  450.   SetRGB4( vp,  1, 10, 10,  7 );     /*  brown   */
  451.   SetRGB4( vp,  2,  0,  0,  0 );     /*  black   */
  452.   SetRGB4( vp,  3, 10,  5,  0 );     /*  brown   */
  453.   SetRGB4( vp,  4, 13, 13,  0 );     /*  yellow  */
  454.   SetRGB4( vp,  5, 11,  7,  0 );     /*  tan     */
  455.   SetRGB4( vp,  6,  0,  0,  0 );     /*  black   */
  456.   SetRGB4( vp,  7,  0, 10,  0 );     /*  green   */
  457.  
  458.   /*  The colors used to slide from one hominid into another: */
  459.   SetRGB4( vp,  8,  15,  0,  1 );
  460.   SetRGB4( vp,  9,  14,  0,  2 );
  461.   SetRGB4( vp, 10,  13,  0,  3 );
  462.   SetRGB4( vp, 11,  12,  0,  4 );
  463.   SetRGB4( vp, 12,  11,  0,  5 );
  464.   SetRGB4( vp, 13,  10,  0,  6 );
  465.   SetRGB4( vp, 14,   9,  0,  7 );
  466.   SetRGB4( vp, 15,   8,  0,  8 );
  467.  
  468. }
  469.  
  470. /*-------------------------------------------------*/
  471. DrawMap()
  472. {
  473.   PLANEPTR  temp_bitplane;
  474.   struct    TmpRas         temp_rast;
  475.   struct    IntuiMessage  *message2;
  476.   int       num_ticks, blue_level, b;
  477.  
  478.   message = 5;
  479.   /*  Dispose of any extraneous messages waiting at our old port:  */
  480.   while ( message != NULL )                        {
  481.     message = GetMsg( evo_window -> UserPort );
  482.     message2 = message;
  483.     if ( message2 != NULL ) ReplyMsg( message2 );   }
  484.  
  485.  
  486.   /*   Describe map window:      */
  487.   nw.IDCMPFlags  = CLOSEWINDOW | INTUITICKS;
  488.   nw.Flags       = WINDOWCLOSE | ACTIVATE;
  489.   nw.Title       = " Map : African Hominid Fossil Sites ";
  490.  
  491.   for( i = 0; i < 8; i++)  SetRGB4( vp,  8+i,    0,  0,  i+6 );
  492.  
  493.   map_window = OpenWindow( &nw );
  494.   if (map_window == NULL)    exit();
  495.  
  496.   rp2 = map_window -> RPort;
  497.  
  498.   temp_bitplane = AllocRaster(640,200);
  499.   if (temp_bitplane == 0) exit();
  500.  
  501.   rp2 -> TmpRas = InitTmpRas( &temp_rast, temp_bitplane, RASSIZE(640,200));
  502.  
  503.   color = 8;
  504.   for ( i = 10; i < 200; i+= 2) {
  505.     color ++;
  506.     color %= 8;
  507.     color += 8;
  508.     SetAPen( rp2, color );
  509.     Move( rp2,   1,  i  );
  510.     Draw( rp2, 638,  i  );
  511.     Move( rp2,   1, i+1 );
  512.     Draw( rp2, 638, i+1 );      } 
  513.  
  514.   SetAPen( rp2, 2 );
  515.  
  516.   Move( rp2, africa[0], africa[1] + 12 );
  517.   for (i = 2; i < sizeof(africa) / 2; i+=2)   {
  518.     Draw( rp2, africa[i], africa[i+1] + 12 ); }
  519.   Draw( rp2, africa[0], africa[1] + 12 );
  520.  
  521.   for( i = 0; i < 142; i+=2)            {
  522.     features[ i ] = feature[ i ];
  523.     features[i+1] = feature[i+1] + 12;  }
  524.  
  525.   Move( rp2, features[0], features[1] );
  526.   for (i = 0; i < 5; i+=2) Draw(rp2,features[i],features[i+1]);
  527.   Draw( rp2, features[0], features[1] );
  528.  
  529.   Move( rp2, features[6], features[7] );
  530.   for (i = 6; i < 13; i+=2) Draw(rp2,features[i],features[i+1]);
  531.   Draw( rp2, features[6], features[7] );
  532.  
  533.   Move( rp2, features[14], features[15] );
  534.   for (i = 14; i < 21; i+=2) Draw(rp2,features[i],features[i+1]);
  535.   Draw( rp2, features[14], features[15] );
  536.  
  537.   Move( rp2, features[22], features[23] );
  538.   for (i = 22; i < 39; i+=2) Draw(rp2,features[i],features[i+1]);
  539.   Draw( rp2, features[22], features[23] );
  540.  
  541.   Move( rp2, features[40], features[41] );
  542.   for (i = 40; i < 45; i+=2) Draw(rp2,features[i],features[i+1]);
  543.   Draw( rp2, features[40], features[41] );
  544.  
  545.   Move( rp2, features[46], features[47] );
  546.   for (i = 46; i < 55; i+=2) Draw(rp2,features[i],features[i+1]);
  547.   Draw( rp2, features[46], features[47] );
  548.  
  549.   Move( rp2, features[56], features[57] );
  550.   for (i = 56; i < 63; i+=2) Draw(rp2,features[i],features[i+1]);
  551.   Draw( rp2, features[56], features[57] );
  552.  
  553.   Move( rp2, features[64], features[65] );
  554.   for (i = 64; i < 73; i+=2) Draw(rp2,features[i],features[i+1]);
  555.   Draw( rp2, features[64], features[65] );
  556.  
  557.   Move( rp2, features[74], features[75] );
  558.   for (i = 74; i < 81; i+=2) Draw(rp2,features[i],features[i+1]);
  559.   Draw( rp2, features[74], features[75] );
  560.  
  561.   Move( rp2, features[82], features[83] );
  562.   for (i = 82; i < 109; i+=2) Draw(rp2,features[i],features[i+1]);
  563.   Draw( rp2, features[82], features[83] );
  564.  
  565.   SetAPen( rp2, 5 );
  566.   SetOPen( rp2, 2 );
  567.   Flood( rp2, 0, 320, 100 );
  568.  
  569.   /*  Plot the fossil sites:  */
  570.   SetAPen( rp2, 2 );
  571.   for (i = 110; i < 141; i+=2)                     {
  572.     WritePixel( rp2,features[i],  features[i+1]);
  573.     WritePixel( rp2,features[i]+1,features[i+1]);  }
  574.  
  575.   SetDrMd( rp2, JAM1 );
  576.   SetAPen( rp2, 4 );
  577.  
  578.   for (i = 0; i < 16; i++)            {
  579.     Move( rp2, 510, 30 + i*10 );
  580.     Text( rp2, fossil_sites[i], 13 ); }
  581.  
  582.   SetAPen( rp2, 2 );
  583.   for ( i = 0; i < 16; i++ )     {
  584.     Move( rp2, features[110 + 2*i] + 4, features[111 + 2*i] );
  585.     Draw( rp2, 505, 26 + i*10 ); }
  586.  
  587.   class      = 0;
  588.   num_ticks  = 0;
  589.   blue_level = 6;
  590.  
  591.   while ( class != CLOSEWINDOW )        {
  592.     WaitPort( map_window -> UserPort );
  593.     message2 = GetMsg( map_window -> UserPort );
  594.     class = message2 -> Class;
  595.     ReplyMsg( message2 );
  596.  
  597.     if ( class == INTUITICKS )     {
  598.  
  599.       /*  Every fourth tick, cycle the background colors: */
  600.       if ( num_ticks++ > 3 ) {
  601.         num_ticks = 0;
  602.         blue_level ++;
  603.         if (blue_level > 13) blue_level = 7;
  604.         
  605.         for( i = 0; i < 8; i++)               {
  606.           b = blue_level + i;
  607.           b %= 8;
  608.           b += 6;
  609.           SetRGB4( vp,  8+i,    0,  0,  b );  }
  610.                              }
  611.                                    }
  612.                                        }
  613.  
  614.   CloseWindow( map_window );
  615.  
  616.   /*  Restore colors to those used by the main Evo window: */
  617.   SetRGB4( vp,  8,  15,  0,  1 );
  618.   SetRGB4( vp,  9,  14,  0,  2 );
  619.   SetRGB4( vp, 10,  13,  0,  3 );
  620.   SetRGB4( vp, 11,  12,  0,  4 );
  621.   SetRGB4( vp, 12,  11,  0,  5 );
  622.   SetRGB4( vp, 13,  10,  0,  6 );
  623.   SetRGB4( vp, 14,   9,  0,  7 );
  624.   SetRGB4( vp, 15,   8,  0,  8 );
  625.  
  626. }
  627.  
  628. /*----------------------------------------------*/
  629.  
  630. DisplayText()
  631. {
  632.   struct    IntuiMessage  *message2;
  633.   char     *text_ptr, delimiter;
  634.   int       red, green, blue, intensity;
  635.   ULONG     seconds, micros;
  636.  
  637.  
  638.   message = 5;
  639.   /*  Dispose of any extraneous messages waiting at our old port:  */
  640.   while ( message != NULL )                         {
  641.     message = GetMsg( evo_window -> UserPort );
  642.     message2 = message;
  643.     if ( message2 != NULL ) ReplyMsg( message2 );   }
  644.  
  645.  
  646.   /*   Describe map window:      */
  647.   nw.IDCMPFlags  = CLOSEWINDOW;
  648.   nw.Flags       = WINDOWCLOSE | ACTIVATE;
  649.  
  650.   if ( selected_box == 1 )
  651.     nw.Title = hominid_title[ hominid ];
  652.   else
  653.     nw.Title = window_title[ selected_box ];
  654.  
  655.   text_window = OpenWindow( &nw );
  656.   if (text_window == NULL)    exit();
  657.  
  658.   rp2 = text_window -> RPort;
  659.  
  660.   CurrentTime(&seconds, µs);
  661.   srand(micros);
  662.  
  663.   red   = rand() % 15;
  664.   green = rand() % 12;
  665.   blue  = rand() %  9;
  666.  
  667.   intensity = red + green + blue;
  668.  
  669.   if (intensity < 26)             {
  670.     red   +=2;
  671.     green +=2;
  672.     if ( red   > 15 ) red   = 15;
  673.     if ( green > 15 ) green = 15; }
  674.  
  675.   SetRGB4( vp, 0, red, green, blue );
  676.  
  677.   SetDrMd( rp2, JAM1 );
  678.   SetAPen( rp2, 2    );
  679.  
  680.   i = 0;
  681.   delimiter = ' ';
  682.  
  683.   while ( delimiter != '?' )    {
  684.  
  685.     if ( selected_box == 1 )                                       {
  686.       /*   We'll pretend there are just 3 for now:                */
  687.  
  688.       if ( hominid == PROCONSUL ) text_ptr = proconsul_text[i];
  689.       if ( hominid == KENYAPITH ) text_ptr = kenyapith_text[i];
  690.       if ( hominid == AFARENSIS ) text_ptr = afarensis_text[i];
  691.       if ( hominid == AFRICANUS ) text_ptr = africanus_text[i];
  692.       if ( hominid == HABILIS   ) text_ptr = habilis_text[i];
  693.       if ( hominid == ERECTUS   ) text_ptr = erectus_text[i];
  694.       if ( hominid == ESAPIENS  ) text_ptr = esapiens_text[i];
  695.       if ( hominid == NEANDER   ) text_ptr = neander_text[i];
  696.       if ( hominid == MSAPIENS  ) text_ptr = msapiens_text[i];
  697.                                                                    }
  698.     else                                                           {
  699.       if (selected_box == 0) text_ptr = help_text[i];
  700.       if (selected_box == 3) text_ptr = glossary_text[i];
  701.       if (selected_box == 4) text_ptr = notes_text[i];             }
  702.  
  703.     delimiter = *text_ptr;
  704.  
  705.     if ( delimiter != '?' ) {
  706.       Move( rp2, 40, 18  + 10 * i );
  707.       Text( rp2, text_ptr, 56 );
  708.       i++;                  }
  709.                                 }
  710.  
  711.   WaitPort( text_window -> UserPort );
  712.   message2 = GetMsg( text_window -> UserPort );
  713.   ReplyMsg( message2 );
  714.  
  715.   SetRGB4( vp,  0,  7,  2,  3 );     /*  plum    */
  716.  
  717.   /*  The only message we were expecting was the window closure:  */
  718.   CloseWindow( text_window );
  719.  
  720. }
  721.