home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 1: Collection A / 17Bit_Collection_A.iso / files / 223.dms / 223.adf / Source / star4.c < prev    next >
C/C++ Source or Header  |  1988-07-25  |  15KB  |  508 lines

  1. /*=========================================================================
  2.   Star4.c -- This module builds and submits a requester in response to
  3.   the user's choice of 'Set Parameters' from the parameters menu
  4.   of the Star Chart program. The requester lets the user modify the 
  5.   longitude, latitude, date, time and observed horizon for their observing
  6.   location.
  7.   
  8.  
  9.   Credits for Star Chart:
  10.        Robert L. Hill of the Orange County, CA. Amiga Friends User Group
  11.                       wrote the original version of StarChart in AmigaBasic
  12.                       The star data and many of the main functions of this
  13.                       version are derived from that program.
  14.  
  15.        Ray R. Larson  wrote the c version 1.0 of StarChart, 'intuitionizing'
  16.                       and enhancing the speed and functions of the original.
  17.  
  18.   Copyright (c) 1986 by Ray R. Larson
  19.   
  20.   This program may be freely distributed and copied, but may not be sold
  21.   without the permission of the author. If you modify or enhance it, 
  22.   please include the above credits (and please send me a copy!).
  23.  
  24. Ray R. Larson
  25. 6425 Central Ave. #304
  26. El Cerrito, CA 94530
  27.  
  28. BitNet  LARSON@UCBCMSA
  29. =========================================================================*/
  30. /*------------Header file for all of the standard stuff----*/ 
  31. /*-------------plus definitions of global structures-------*/
  32. #include "star.h" 
  33.  
  34. /*  Definitions for Gadget ID numbers  (see Star3.c)         */ 
  35. #define  LONGDEGGAD   0
  36. #define  LONGMINGAD   1
  37. #define  LATDEGGAD   2
  38. #define  YEARGAD   3
  39. #define  MONGAD   4
  40. #define  DAYGAD   5
  41. #define  HOURGAD   6
  42. #define  MINGAD   7
  43. #define  SECGAD   8
  44. #define  NORTHGAD   9
  45. #define  SOUTHGAD   10
  46. #define  CANGAD   11
  47. #define  OKGAD   12
  48. /* another macro */
  49. #define ABS(x) ((x<0)?(-(x)):(x))
  50.  
  51. /****************************************************************************
  52.  *  Global Structures 
  53.  ***************************************************************************/
  54.  
  55. /* the newwindow structure used in GT */
  56. extern struct NewWindow nw;
  57. extern struct Window *w;
  58. extern SHORT SecondsCount;
  59. extern struct ParamStruct Parms;
  60. extern SHORT Dd[],DSum[]; /* tables of days per month- in starglb.c */
  61.  
  62. /****************************************************************************
  63.  * External function definitions
  64.  ***************************************************************************/
  65. extern struct IntuiMessage *GetMsg();
  66.  
  67. /****************************************************************************
  68.  * Requester structure and global pointer to it's gadget list.
  69.  ***************************************************************************/
  70. struct Requester ParamRequester;
  71. struct ParamStruct workParms;
  72.  
  73. extern struct Gadget *ParamGads, north, south, day;
  74.  
  75. /* Integer string gadgets - defined in star3.c */
  76. extern struct Gadget sec, min, hour, day, mon, year,
  77.        LatDeg, LongMin, LongDeg;
  78.  
  79. /**********************************************************************
  80.  *  Border Definitions for the requester
  81.  **********************************************************************/
  82.  
  83. SHORT Req_Pairs2[] = {
  84.   1,     1,   
  85.   358,     1,   
  86.   358,     188,   
  87.   1,     188,   
  88.   1,     1    
  89. };
  90. SHORT Req_Pairs1[] = {
  91.   0,     0,   
  92.   362,     0,   
  93.   362,     192,   
  94.   0,     192,   
  95.   0,     0    
  96. };
  97.  
  98. struct Border Req_bord_2 = {
  99.   2, 2,       /* LeftEdge, TopEdge */
  100.   1,  7,  JAM1,  /* FrontPen, BackPen, DrawMode*/
  101.   5,             /* Count of XY pairs */  
  102.   (SHORT *)&Req_Pairs2, /* XY pairs */
  103.   NULL           /* Next Border */
  104. };
  105.  
  106. struct Border Req_bord_1 = {
  107.   0,  0,       /* LeftEdge, TopEdge */
  108.   7,  3,  JAM1,  /* FrontPen, BackPen, DrawMode*/
  109.   5,             /* Count of XY pairs */  
  110.   (SHORT *)&Req_Pairs1, /* XY pairs */
  111.   &Req_bord_2           /* Next Border */
  112. };
  113.  
  114. extern struct TextAttr TxtAt_BU;
  115.  
  116. struct IntuiText Req_Text = {
  117.    2, 7,     /* FrontPen, BackPen */
  118.    JAM2,       /* DrawMode */
  119.    50, 1,     /* LeftEdge, TopEdge */
  120.    &TxtAt_BU, /* ITextFont Pointer */ 
  121.    /* The IText */
  122.    (UBYTE *)"    Parameters for Star Chart    ",
  123.    NULL    /* NextText */
  124.  };
  125.  
  126. extern struct TextAttr TxtAt_B;
  127.  
  128. struct IntuiText Error_Text = {
  129.    3, 2,     /* FrontPen, BackPen */
  130.    JAM2,       /* DrawMode */
  131.    0, 0,     /* LeftEdge, TopEdge */
  132.    &TxtAt_B, /* ITextFont Pointer */ 
  133.    /* The IText */
  134.    (UBYTE *)"?",
  135.    NULL    /* NextText */
  136.  };
  137.  
  138. /****************************************************************************
  139.  *               The Code part of the GetParam module.
  140.  ***************************************************************************/
  141. GetParams()
  142. {
  143.   BOOL cancelchosen;
  144.   LONG iflags;
  145.   struct RastPort *reqrp;
  146.  
  147.  
  148.   /* fix the IDCMP flags to report requester set and clear */
  149.   iflags = nw.IDCMPFlags;
  150.   iflags |= REQCLEAR;
  151.   ModifyIDCMP(w,iflags);
  152.   
  153.  
  154.       /* initialize the text Param requester */ 
  155.       InitParamReq();
  156.  
  157.       /* Put up the requester  */ 
  158.       Request(&ParamRequester,w);
  159.       
  160.       /* set the north/south imagery */
  161.        reqrp = ParamRequester.ReqLayer->rp;
  162.  
  163.        if(workParms.Horizon == 0)
  164.          { SetDrMd(reqrp, COMPLEMENT);
  165.            RectFill(reqrp,94L,153L,158L,169L);
  166.            SetDrMd(reqrp, JAM1);
  167.           }
  168.        else
  169.           { SetDrMd(reqrp, COMPLEMENT);
  170.            RectFill(reqrp,206L,153L,274L,169L);
  171.            SetDrMd(reqrp, JAM1);
  172.           }
  173.  
  174.       /* let the user fill in the parameters and wait for a cancel or ok. */  
  175.       cancelchosen = WaitParamReq(reqrp);
  176.       
  177.       /* if the user cancelled, just return -- otherwise set Parms and    */
  178.       /* re-calculate and redisplay the star chart.                       */
  179.       if (cancelchosen) return(0);
  180.       
  181.       /* figure out current siderial time, etc. and update the Parms struct */
  182.       CalcParams(&workParms);
  183.       Parms = workParms;
  184.       
  185.       /* recalculate star positions and display them. */
  186.       DisplayStars();
  187.       DisplayAllText();
  188.       
  189. } /* GetParams */
  190.  
  191. /*
  192.  *  Init the Itext Param requester
  193.  */
  194. InitParamReq()
  195.   struct RastPort *reqrp;
  196.   
  197.   InitRequester(&ParamRequester);
  198.   ParamRequester.LeftEdge  = 110;
  199.   ParamRequester.TopEdge   = 2;
  200.   ParamRequester.Width     = 363;
  201.   ParamRequester.Height    = 193;
  202.   ParamRequester.ReqGadget = ParamGads;
  203.   ParamRequester.ReqText   = &Req_Text;
  204.   ParamRequester.BackFill  = 2;
  205.   ParamRequester.Flags     = 0;
  206.   ParamRequester.ReqBorder = &Req_bord_1;
  207.   
  208.   /* copy the parms structure */
  209.   workParms = Parms;
  210.  
  211.    InitStringGad(&sec,SecondsCount);
  212.    InitStringGad(&min,workParms.Minute);
  213.    InitStringGad(&hour,workParms.Hour);
  214.    InitStringGad(&day,workParms.Day);
  215.    InitStringGad(&mon,workParms.Month);
  216.    InitStringGad(&year,workParms.Year);
  217.    InitStringGad(&LatDeg,workParms.Latitude);
  218.    InitStringGad(&LongMin,workParms.LongitudeMin);
  219.    InitStringGad(&LongDeg,workParms.LongitudeDeg);
  220.  
  221.  
  222. } /* InitParamReq */
  223.  
  224.  
  225. InitStringGad(gad,val)
  226. struct Gadget *gad;
  227. SHORT val;
  228. {
  229.   struct StringInfo *si;
  230.   
  231.   si = (struct StringInfo *)gad->SpecialInfo;
  232.   sprintf(si->Buffer,"%d",val);
  233.   si->NumChars = (LONG)strlen(si->Buffer);
  234.   *(si->UndoBuffer) = '\0';
  235. }
  236.  
  237.   
  238. /****************************************************************************
  239.  *  WaitParamReq - permit user to change the values in the parameter gadgets
  240.  *                 and check the values they install until either the 
  241.  *                 CANCEL gadget is clicked or the OK gadget is clicked AND
  242.  *                 there are no outstanding input errors
  243.  ***************************************************************************/
  244. BOOL WaitParamReq(reqrp)
  245. struct RastPort *reqrp;
  246. {
  247.   ULONG  class = GADGETDOWN;
  248.   USHORT Param = 0;
  249.   USHORT selected = 0;
  250.   struct IntuiMessage *message;
  251.   struct Gadget *gadget, *lastgad;
  252.   BOOL cancelflag = FALSE;
  253.   LONG  errorflag = 0L, checkvals();
  254.  
  255.   lastgad =  NULL;
  256.  
  257.   while (class != REQCLEAR)
  258.     {
  259.     if ((message=(struct IntuiMessage *) GetMsg(w->UserPort)) == 0L)
  260.       {
  261.       Wait(1L<<w->UserPort->mp_SigBit);
  262.       continue;
  263.       }
  264.  
  265.     class  = message->Class;
  266.     gadget = (struct Gadget *) message->IAddress;
  267.     ReplyMsg(message);
  268.     switch (class)
  269.       {
  270.       case GADGETDOWN: /* check to see if the user clicked on a new */
  271.                /* gadget withou hitting return on the old one */
  272.                /* if so, treat this like a gadgetup for the   */
  273.                /* previous gadget.                     */
  274.  
  275.               if (lastgad == NULL) 
  276.              errorflag = checkvals(reqrp,gadget,errorflag,class);
  277.                       else
  278.              errorflag = checkvals(reqrp,lastgad,errorflag,class);
  279.                      lastgad = gadget;
  280.                       break;
  281.  
  282.       case GADGETUP: 
  283.          switch (gadget->GadgetID)
  284.         {
  285.         case  NORTHGAD: 
  286.                       if(workParms.Horizon != 0)
  287.                         { SetDrMd(reqrp, COMPLEMENT);
  288.                           RectFill(reqrp,94L,153L,158L,169L);
  289.                           RectFill(reqrp,206L,153L,274L,169L);
  290.                           SetDrMd(reqrp, JAM1);
  291.                          }
  292.              workParms.Horizon = 0;
  293.              break;   
  294.              
  295.         case  SOUTHGAD: 
  296.                       if(workParms.Horizon != 1)
  297.                         { SetDrMd(reqrp, COMPLEMENT);
  298.                           RectFill(reqrp,94L,153L,158L,169L);
  299.                      RectFill(reqrp,206L,153L,274L,169L);
  300.                           SetDrMd(reqrp, JAM1);
  301.                          }
  302.              workParms.Horizon = 1;
  303.              break;   
  304.         
  305.  
  306.         case  CANGAD : 
  307.                      cancelflag = TRUE;
  308.                              break; 
  309.  
  310.                    case  OKGAD  :
  311.                   if (errorflag == 0) 
  312.                      EndRequest(&ParamRequester,w);
  313.                  else DisplayBeep(w->WScreen);    
  314.                  break;
  315.  
  316.                 default: errorflag = checkvals(reqrp,gadget,errorflag,class);
  317.  
  318.              } /* end of GADGETUP switch */
  319.  
  320.         } /* end of CLASS switch */
  321.     }/* end of while loop */
  322.     
  323.  
  324. return(cancelflag);
  325.        
  326. } /* WaitParamReq */
  327.    
  328. /****************************************************************************
  329.  *  checkvals - verify that the values returned by the integer gadgets are
  330.  *              in the appropriate range for the parameter.
  331.   ***************************************************************************/
  332. LONG checkvals(reqrp,checkgad,errorflag,class)
  333. struct RastPort *reqrp;
  334. struct Gadget *checkgad;
  335. LONG errorflag;
  336. ULONG class;
  337. {
  338.   struct StringInfo *si;
  339.   BOOL  inputerror = FALSE;
  340.   LONG  checknum, pendingerror;
  341.  
  342.    if (checkgad == NULL) return(errorflag);
  343.    pendingerror = errorflag;
  344.  
  345.    si = (struct StringInfo *)checkgad->SpecialInfo;
  346.    if (si == NULL) return(errorflag);
  347.  
  348.   /* this is kind of a kludge, but necessary since Intuition will have set */
  349.   /* LongInt to zero, IF the user clicks on a gadget THEN  clicks on       */
  350.   /* another, without hitting return on the old one and not modifying the  */
  351.   /* contents of the string buffer, the LongInt value for the gadget is    */
  352.   /* reported as zero.                               */ 
  353.   if (class == GADGETUP) checknum = si->LongInt;
  354.   else checknum = atol(si->Buffer);
  355.      
  356.   /* check the values input */
  357.   switch (checkgad->GadgetID)
  358.        {
  359.     case  LONGDEGGAD: 
  360.           if (INRANGE(checknum,-180L,180L))
  361.             { workParms.LongitudeDeg = checknum;
  362.               errorflag &= ~(1L << LONGDEGGAD);
  363.           break;
  364.         }
  365.           else inputerror = TRUE;
  366.           break;
  367.             
  368.     case  LONGMINGAD:
  369.           if (INRANGE(checknum,0L,59L))
  370.             { workParms.LongitudeMin = checknum;
  371.               errorflag &= ~(1L << LONGMINGAD);
  372.           break;
  373.         }
  374.           else inputerror = TRUE;
  375.           break;   
  376.             
  377.     case  LATDEGGAD: 
  378.           if (INRANGE(checknum,0L,90L))
  379.             { workParms.Latitude = checknum;
  380.               errorflag &= ~(1L << LATDEGGAD);
  381.           break;
  382.         }
  383.           else inputerror = TRUE;
  384.         break;   
  385.             
  386.     case  YEARGAD:
  387.           if (INRANGE(checknum,1900L,2100L))
  388.             { workParms.Year = checknum;
  389.               errorflag &= ~(1L << YEARGAD);
  390.           break;
  391.         }
  392.           else inputerror = TRUE;
  393.         break;   
  394.              
  395.     case  MONGAD:
  396.           if (INRANGE(checknum,1L,12L))
  397.             { workParms.Month = checknum;
  398.               errorflag &= ~(1L << MONGAD);
  399.           if ((INRANGE(workParms.Day,1,Dd[workParms.Month])) == 0)
  400.              { 
  401.                    checkgad = &day;
  402.                si = (struct StringInfo *)checkgad->SpecialInfo;
  403.                        inputerror = TRUE;
  404.                break;
  405.               }
  406.          break;
  407.         }
  408.           else inputerror = TRUE;
  409.         break;   
  410.              
  411.     case  DAYGAD:
  412.           if (INRANGE(checknum,1L,(LONG)Dd[workParms.Month]))
  413.             { workParms.Day = checknum;
  414.               errorflag &= ~(1L << DAYGAD);
  415.           break;
  416.         }
  417.           else inputerror = TRUE;
  418.           break;   
  419.              
  420.     case  HOURGAD:
  421.           if (INRANGE(checknum,0L,23L))
  422.             { workParms.Hour = checknum;
  423.               errorflag &= ~(1L << HOURGAD);
  424.           break;
  425.         }
  426.           else inputerror = TRUE;
  427.           break;   
  428.              
  429.     case  MINGAD:
  430.           if (INRANGE(checknum,0L,59L))
  431.             { workParms.Minute = checknum;
  432.               errorflag &= ~(1L << MINGAD);
  433.           break;
  434.         }
  435.           else inputerror = TRUE;
  436.          break;   
  437.              
  438.     case  SECGAD:
  439.           if (INRANGE(checknum,0L,59L))
  440.             { SecondsCount = checknum;
  441.               errorflag &= ~(1L << SECGAD);
  442.           break;
  443.         }
  444.           else inputerror = TRUE;
  445.          break;   
  446.      } /* end of Gadget id switch */
  447.  
  448.     if (inputerror == TRUE) /* put a "?" next to the gadget */
  449.       { 
  450.         errorflag |= (1L << checkgad->GadgetID);
  451.         DisplayBeep(w->WScreen);
  452.         PrintIText(reqrp,&Error_Text,
  453.           (LONG)(checkgad->LeftEdge - 10),(LONG)checkgad->TopEdge);
  454.       }
  455.  
  456.     if ((pendingerror != errorflag) && (inputerror == FALSE))
  457.       { /* user must have fixed an error, so turn off the ? */
  458.         pendingerror = errorflag;
  459.         Error_Text.FrontPen = 2;
  460.         PrintIText(reqrp,&Error_Text,
  461.           (LONG)(checkgad->LeftEdge - 10),(LONG)checkgad->TopEdge);
  462.         Error_Text.FrontPen = 3;
  463.       }
  464. return(errorflag);
  465.        
  466. } /* end of checkvals */
  467.  
  468.  
  469. /*************************************************************************
  470.  *  CalcParams - Calculate local siderial time (Lst) and Greenwich
  471.  *               siderial time based on the current work parameters.
  472.  ************************************************************************/
  473. CalcParams(p)
  474. struct ParamStruct *p;
  475. {
  476.   FLOAT workhours, LocalOffset, MeanLocTime;
  477.   FLOAT CalcGst(); /* calcGst is in starglb.c */
  478.   SHORT degrees, temp;
  479.  
  480.   
  481.   degrees = ABS(p->LongitudeDeg) % 15;
  482.   workhours = (FLOAT)degrees 
  483.         + ((FLOAT)p->LongitudeMin / 60.0);
  484.   LocalOffset = (workhours * 4.0)/60.0;
  485.   
  486.  /* get Greenwich time */
  487.   p->Gst = CalcGst(p->Day,p->Month);
  488.   workhours = (FLOAT)p->Hour + ((FLOAT)p->Minute / 60.0);
  489.   if(p->LongitudeDeg < 0)
  490.      MeanLocTime = workhours + LocalOffset;
  491.   else 
  492.      MeanLocTime = workhours - LocalOffset;
  493.      
  494.   /* local siderial time */
  495.   p->Lst = MeanLocTime + p->Gst;
  496.   if (p->Lst > 24.0) 
  497.      p->Lst -= 24.0;
  498.   if (p->Lst < 0) 
  499.      p->Lst += 24;
  500.   
  501.   /* set siderial times in the workparms */
  502.   temp = (SHORT)(p->Lst * 60.0);
  503.   p->Hr = temp / 60;
  504.   p->Mn = temp % 60;
  505. }
  506.  
  507.