home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 306.lha / Gravity-Well / GW-Interface.c < prev    next >
Text File  |  1980-12-03  |  69KB  |  1,986 lines

  1. /*
  2.       GW-Interface.c
  3.       Graphics and user control for Geavity-Well
  4.       Gary Teachout
  5.       Copyright   July 1989
  6.       lc -x -cs GW-Interface     To compile with Lattice 5.0
  7. */
  8.  
  9.  
  10.  #include "GW-Include.h"
  11.  
  12.  
  13.  void startup()
  14.  {
  15.    int   i  ;
  16.    char  *p  ;
  17.  
  18.  
  19.    IntuitionBase = ( struct IntuitionBase * )
  20.                    OpenLibrary( "intuition.library" , 33 )  ;
  21.    if ( ! IntuitionBase )
  22.       cleanup()  ;
  23.  
  24.    GfxBase = ( struct GfxBase * )
  25.              OpenLibrary( "graphics.library" , 33 )  ;
  26.    if ( ! GfxBase )
  27.       cleanup()  ;
  28.  
  29.    DiskfontBase = ( struct Library * )
  30.                   OpenLibrary( "diskfont.library" , 33 )  ;
  31.    if ( ! DiskfontBase )
  32.       cleanup()  ;
  33.  
  34.    rfont = OpenDiskFont( &rtext )  ;
  35.    if ( ! rfont )
  36.       cleanup()  ;
  37.  
  38.    ns.Font = &stext  ;
  39.    screen = OpenScreen( &ns )  ;
  40.    if ( ! screen )
  41.       cleanup()  ;
  42.  
  43.    for ( i = 0 ; i < 4 ; i ++ )
  44.       SetRGB4( &screen->ViewPort , i ,    clut[ i ][ 0 ] ,
  45.                                           clut[ i ][ 1 ] ,
  46.                                           clut[ i ][ 2 ]  )  ;
  47.  
  48.    controlnw.Screen = screen  ;
  49.    viewcontrolnw.Screen = screen  ;
  50.    mainviewnw.Screen = screen  ;
  51.    topviewnw.Screen = screen  ;
  52.    rightviewnw.Screen = screen  ;
  53.  
  54.    for ( i = 0 ; i < 12 ; i ++ )
  55.    {
  56.       viewcongadg[ i ].GadgetID = i  ;
  57.       viewcongadg[ i ].NextGadget = ( i < 11 ) ? &viewcongadg[ i + 1 ] : NULL ;
  58.    }
  59.    viewcontrolnw.FirstGadget = &viewcongadg[ 0 ]  ;
  60.  
  61.    for ( i = 0 ; i < 45 ; i ++ )
  62.    {
  63.       controlgadg[ i ].GadgetID = i  ;
  64.       controlgadg[ i ].NextGadget = ( i < 44 ) ? &controlgadg[ i + 1 ] : NULL ;
  65.    }
  66.    controlnw.FirstGadget = &controlgadg[ 0 ]  ;
  67.  
  68.    for ( i = 0 ; i < 14 ; i ++ )
  69.    {
  70.       controlgadg[ 31 + i ].SpecialInfo = ( APTR ) &controlinfo[ i ]  ;
  71.       controlinfo[ i ].UndoBuffer = undobuffer  ;
  72.    }
  73.    for ( i = 0 ; i < 4 ; i ++ )
  74.    {
  75.       controlinfo[ i ].MaxChars = 66  ;
  76.       controlgadg[ 31 + i ].GadgetRender = ( APTR ) &textbox  ;
  77.    }
  78.    for ( i = 4 ; i < 14 ; i ++ )
  79.    {
  80.       controlinfo[ i ].MaxChars = 33  ;
  81.       controlinfo[ i ].Buffer = &numberbuff[ i - 4 ][ 0 ]  ;
  82.       controlgadg[ 31 + i ].GadgetRender = ( APTR ) &numberbox  ;
  83.    }
  84.    controlinfo[ 0 ].MaxChars = 100  ;
  85.    controlinfo[ 0 ].Buffer = filename  ;
  86.    controlinfo[ 1 ].Buffer = g.filecomment1  ;
  87.    controlinfo[ 2 ].Buffer = g.filecomment2  ;
  88.    controlinfo[ 3 ].Buffer = &g.objects[ g.objectnum ].name[ 0 ]  ;
  89.  
  90.    textbox.XY = &xytextbox[ 0 ]  ;
  91.    numberbox.XY = &xynumbox[ 0 ]  ;
  92.  
  93.    control = OpenWindow( &controlnw )  ;
  94.    if ( ! control )
  95.       cleanup()  ;
  96.  
  97.    SetFont( control->RPort , rfont )  ;
  98.  
  99.    openmainview()  ;
  100.    if ( ! mainview )
  101.       cleanup()  ;
  102.  
  103.    SetAPen( control->RPort , BPEN )  ;
  104.    Move( control->RPort , 90 , 10 )  ;
  105.    Draw( control->RPort , 90 , 217 )  ;
  106.    Draw( control->RPort , 638 , 217 )  ;
  107.  
  108.    SetBPen( control->RPort , LINEPEN )  ;
  109.    SetAPen( control->RPort , DOTPEN )  ;
  110.    for ( i = 0 ; i < 20 ; i ++ )
  111.    {
  112.       Move( control->RPort , 10 , 21 + ( i * 14 ) )  ;
  113.       Text( control->RPort , &numbertext[ i * 3 ] , 4 )  ;
  114.    }
  115.    for ( i = 0 ; i < 11 ; i ++ )
  116.    {
  117.       Move( control->RPort , controlgadg[ 20 + i ].LeftEdge + 4 ,
  118.                              controlgadg[ 20 + i ].TopEdge + 9 )  ;
  119.       Text( control->RPort , controlgtext[ i ] , 8 )  ;
  120.    }
  121.  
  122.    SetBPen( control->RPort , 0 )  ;
  123.    SetAPen( control->RPort , DOTPEN )  ;
  124.    Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) )  ;
  125.    Text( control->RPort , "<-" , 2 )  ;
  126.    Move( control->RPort , 48 , 21 + ( 0 * 14 ) )  ;
  127.    Text( control->RPort , "*" , 1 )  ;
  128.    Move( control->RPort , 48 , 21 + ( 1 * 14 ) )  ;
  129.    Text( control->RPort , "*" , 1 )  ;
  130.    Move( control->RPort , 48 , 21 + ( 2 * 14 ) )  ;
  131.    Text( control->RPort , "*" , 1 )  ;
  132.    for ( i = 0 ; i < 10 ; i ++ ) 
  133.    {
  134.       Move( control->RPort , controlgadg[ 31 + i ].LeftEdge + 5 ,
  135.                              controlgadg[ 31 + i ].TopEdge - 7 )  ;
  136.       Text( control->RPort , conlabel[ i ] , conlabellength[ i ] )  ;
  137.    }
  138.    Move( control->RPort , 150 , 23 )  ;
  139.    Text(    control->RPort , 
  140.             "Gravity Well   Celestial Motion Simulator" , 41 )  ;
  141.    Move( control->RPort , 150 , 38 )  ;
  142.    Text(    control->RPort , 
  143.             "by  Gary Teachout   Freeware   Copyright 1989" , 45 )  ;
  144.    Move( control->RPort , 130 , 197 )  ;
  145.    Text( control->RPort , "Scale:" , 6 )  ;
  146.    p = gcvt( g.scale , DBL_DIG , &ettext[ 0 ] )  ;
  147.    Move( control->RPort , 234 , 197 )  ;
  148.    Text( control->RPort ,  &ettext[ 0 ] , strlen( &ettext[ 0 ] ) )  ;
  149.    Move( control->RPort , 130 , 211 )  ;
  150.    Text( control->RPort , "Elaped Time:" , 12 )  ;
  151.    Move( control->RPort , 88 , 346 )  ;
  152.    Text( control->RPort , "X" , 1 )  ;
  153.    Move( control->RPort , 88 , 360 )  ;
  154.    Text( control->RPort , "Y" , 1 )  ;
  155.    Move( control->RPort , 88 , 374 )  ;
  156.    Text( control->RPort , "Z" , 1 )  ;
  157.  
  158.    menustrip[ 0 ].FirstItem = &menu0[ 0 ].item  ;
  159.    menu0[ 0 ].item.ItemFill = ( APTR ) &menu0[ 0 ].text  ;
  160.    menu0[ 0 ].text.ITextFont = &rtext  ;
  161.  
  162.    menustrip[ 1 ].FirstItem = &menu1[ 0 ].item  ;
  163.    for ( i = 0 ; i < 5 ; i ++ )
  164.    {
  165.       menu1[ i ].item.ItemFill = ( APTR ) &menu1[ i ].text  ;
  166.       menu1[ i ].text.ITextFont = &rtext  ;
  167.       menu1[ i ].item.NextItem = ( i < 4 ) ? &menu1[ i + 1 ].item : NULL ;
  168.    }
  169.  
  170.    menustrip[ 2 ].FirstItem = &menu2[ 0 ].item  ;
  171.    for ( i = 0 ; i < 4 ; i ++ )
  172.    {
  173.       menu2[ i ].item.ItemFill = ( APTR ) &menu2[ i ].text  ;
  174.       menu2[ i ].text.ITextFont = &rtext  ;
  175.       menu2[ i ].item.NextItem = ( i < 3 ) ? &menu2[ i + 1 ].item : NULL ;
  176.    }
  177.  
  178.    menustrip[ 0 ].NextMenu = &menustrip[ 1 ]  ;
  179.    menustrip[ 1 ].NextMenu = &menustrip[ 2 ]  ;
  180.  
  181.    SetMenuStrip( control , &menustrip[ 0 ] )  ;
  182.  
  183.    openviewcontrol()  ;
  184.    opentopview()  ;
  185.    openrightview()  ;
  186.    openviewcontrol()  ;
  187.  
  188.    set()  ;
  189.  }
  190.  
  191.  
  192.  void cleanup()  
  193.  {
  194.    if ( control )
  195.    {
  196.       ClearMenuStrip( control )  ;
  197.       CloseWindow( control )  ;
  198.    }
  199.  
  200.    if ( viewcontrol )
  201.    {
  202.       ClearMenuStrip( viewcontrol )  ;
  203.       CloseWindow( viewcontrol )  ;
  204.    }
  205.  
  206.    if ( mainview )
  207.    {
  208.       ClearMenuStrip( mainview )  ;
  209.       CloseWindow( mainview )  ;
  210.    }
  211.  
  212.    if ( topview )
  213.    {
  214.       ClearMenuStrip( topview )  ;
  215.       CloseWindow( topview )  ;
  216.    }
  217.  
  218.    if ( rightview )
  219.    {
  220.       ClearMenuStrip( rightview )  ;
  221.       CloseWindow( rightview )  ;
  222.    }
  223.  
  224.    if ( screen )
  225.       CloseScreen( screen )  ;
  226.  
  227.    if ( rfont )
  228.       CloseFont( rfont )  ;
  229.  
  230.    if ( DiskfontBase )
  231.       CloseLibrary( DiskfontBase )  ;
  232.  
  233.    if ( GfxBase )
  234.       CloseLibrary( GfxBase )  ;
  235.  
  236.    if ( IntuitionBase )
  237.       CloseLibrary( IntuitionBase )  ;
  238.  
  239.    exit()  ;
  240.  }
  241.  
  242.  
  243.  void openmainview()
  244.  {
  245.    if ( mainview )
  246.    {
  247.       WindowToFront( mainview )  ;
  248.    }
  249.    else
  250.    {
  251.       mainview = OpenWindow( &mainviewnw )  ;
  252.       if ( mainview )
  253.       {
  254.          SetMenuStrip( mainview , &menustrip[ 0 ] )  ;
  255.          setupdisplay( mainview )  ;
  256.       }
  257.       else
  258.       {
  259.          DisplayBeep( screen )  ;
  260.       }
  261.    }
  262.  }
  263.  
  264.  
  265.  void opentopview()
  266.  {
  267.    if ( topview )
  268.    {
  269.       WindowToFront( topview )  ;
  270.    }
  271.    else
  272.    {
  273.       topview = OpenWindow( &topviewnw )  ;
  274.       if ( topview )
  275.       {
  276.          SetMenuStrip( topview , &menustrip[ 0 ] )  ;
  277.          setupdisplay( topview )  ;
  278.       }
  279.       else
  280.       {
  281.          DisplayBeep( screen )  ;
  282.       }
  283.    }
  284.  }
  285.  
  286.  
  287.  void openrightview()
  288.  {
  289.    if ( rightview )
  290.    {
  291.       WindowToFront( rightview )  ;
  292.    }
  293.    else
  294.    {
  295.       rightview = OpenWindow( &rightviewnw )  ;
  296.       if ( rightview )
  297.       {
  298.          SetMenuStrip( rightview , &menustrip[ 0 ] )  ;
  299.          setupdisplay( rightview )  ;
  300.       }
  301.       else
  302.       {
  303.          DisplayBeep( screen )  ;
  304.       }
  305.    }
  306.  }
  307.  
  308.  
  309.  void openviewcontrol()
  310.  {
  311.    long    i  ;
  312.  
  313.    if ( viewcontrol )
  314.    {
  315.       WindowToFront( viewcontrol )  ;
  316.    }
  317.    else
  318.    {
  319.       viewcontrol = OpenWindow( &viewcontrolnw )  ;
  320.       if ( viewcontrol )
  321.       {
  322.          SetFont( viewcontrol->RPort , rfont )  ;
  323.          SetMenuStrip( viewcontrol , &menustrip[ 0 ] )  ;
  324.          SetBPen( viewcontrol->RPort , LINEPEN )  ;
  325.          SetAPen( viewcontrol->RPort , DOTPEN )  ;
  326.          for ( i = 0 ; i < 3 ; i ++ )
  327.          {
  328.             Move( viewcontrol->RPort , 14 , 86 + ( i * 16 ) )  ;
  329.             Text( viewcontrol->RPort , "<" , 1 )  ;
  330.             Move( viewcontrol->RPort , 78 , 86 + ( i * 16 ) )  ;
  331.             Text( viewcontrol->RPort , ">" , 1 )  ;
  332.          }            
  333.          Move( viewcontrol->RPort , 18 , 22 + ( 0 * 16 ) )  ;
  334.          Text( viewcontrol->RPort , " Follow " , 8 )  ;
  335.          Move( viewcontrol->RPort , 18 , 22 + ( 1 * 16 ) )  ;
  336.          Text( viewcontrol->RPort , " Center " , 8 )  ;
  337.          Move( viewcontrol->RPort , 18 , 22 + ( 2 * 16 ) )  ;
  338.          Text( viewcontrol->RPort , " Trails " , 8 )  ;
  339.                 
  340.          Move( viewcontrol->RPort , 22 , 22 + ( 7 * 16 ) )  ;
  341.          Text( viewcontrol->RPort , " Reset " , 7 )  ;
  342.          Move( viewcontrol->RPort , 14 , 22 + ( 9 * 16 ) )  ;
  343.          Text( viewcontrol->RPort , "IN" , 2 )  ;
  344.          Move( viewcontrol->RPort , 62 , 22 + ( 9 * 16 ) )  ;
  345.          Text( viewcontrol->RPort , "OUT" , 3 )  ;
  346.  
  347.          SetBPen( viewcontrol->RPort , 0 )  ;
  348.  
  349.          Move( viewcontrol->RPort , 18 , 22 + ( 3 * 16 ) )  ;
  350.          Text( viewcontrol->RPort , "-Rotate-" , 8 )  ;
  351.          Move( viewcontrol->RPort , 34 , 22 + ( 4 * 16 ) )  ;
  352.          Text( viewcontrol->RPort , "Main" , 4 )  ;
  353.          Move( viewcontrol->RPort , 38 , 22 + ( 5 * 16 ) )  ;
  354.          Text( viewcontrol->RPort , "Top" , 3 )  ;
  355.          Move( viewcontrol->RPort , 30 , 22 + ( 6 * 16 ) )  ;
  356.          Text( viewcontrol->RPort , "Right" , 5 )  ;
  357.          Move( viewcontrol->RPort , 26 , 22 + ( 8 * 16 ) )  ;
  358.          Text( viewcontrol->RPort , "-Zoom-" , 6 )  ;
  359.       }                            
  360.       else
  361.          DisplayBeep( screen )  ;
  362.    }
  363.  }
  364.  
  365.  
  366.  void pixel( w , x , y )
  367.    struct Window  *w  ;               
  368.    double         x , y  ;
  369.  {
  370.    long     xx , yy  ;
  371.  
  372.    xx =     ( w->Width >> 1 ) 
  373.          +  ( long ) ( g.scale * x * 200.0 )  ;
  374.    yy =     ( w->Height >> 1 )
  375.          -  ( long ) ( g.scale * y * 177.0 )  ;
  376.  
  377.    if (     ( xx > w->BorderLeft ) 
  378.          && ( xx < ( w->Width - w->BorderRight ) )
  379.          && ( yy > w->BorderTop ) 
  380.          && ( yy < ( w->Height - w->BorderBottom ) ) )
  381.    {
  382.       WritePixel( w->RPort , xx , yy )  ; 
  383.       WritePixel( w->RPort , xx + 1 , yy )  ; 
  384.    }
  385.  }
  386.  
  387.  
  388.  void blankwindow( w )
  389.    struct Window  *w  ;
  390.  {
  391.    if ( w )
  392.    {
  393.       SetAPen( w->RPort , 0 )  ;
  394.       RectFill( w->RPort ,    w->BorderLeft - 1 ,
  395.                               w->BorderTop - 1 ,
  396.                               w->Width - w->BorderRight ,
  397.                               w->Height - w->BorderBottom )  ;
  398.    }
  399.  }
  400.  
  401.  
  402.  void line( w , x1 , y1 , x2 , y2 )
  403.    struct Window  *w  ;
  404.    double         x1 , y1 , x2 , y2  ;
  405.  {
  406.    long     xx1 , yy1 , xx2 , yy2  ;
  407.  
  408.    xx1 =    ( w->Width >> 1 ) 
  409.          +  ( long ) ( g.scale * x1 * 200.0 )  ;
  410.    yy1 =    ( w->Height >> 1 )
  411.          -  ( long ) ( g.scale * y1 * 177.0 )  ;
  412.    xx2 =    ( w->Width >> 1 ) 
  413.          +  ( long ) ( g.scale * x2 * 200.0 )  ;
  414.    yy2 =    ( w->Height >> 1 )
  415.          -  ( long ) ( g.scale * y2 * 177.0 )  ;
  416.  
  417.    if (     ( xx1 > w->BorderLeft ) 
  418.          && ( xx1 < ( w->Width - w->BorderRight ) )
  419.          && ( yy1 > w->BorderTop ) 
  420.          && ( yy1 < ( w->Height - w->BorderBottom ) )
  421.          && ( xx2 > w->BorderLeft ) 
  422.          && ( xx2 < ( w->Width - w->BorderRight ) )
  423.          && ( yy2 > w->BorderTop ) 
  424.          && ( yy2 < ( w->Height - w->BorderBottom ) ) )
  425.    {
  426.       Move( w->RPort , xx1 , yy1 )  ;
  427.       Draw( w->RPort , xx2 , yy2 )  ;
  428.    }
  429.  }
  430.  
  431.  
  432.  void linelong( w , x1 , y1 , x2 , y2 )
  433.    struct Window  *w  ;
  434.    long           x1 , y1 , x2 , y2  ;
  435.  {
  436.    if ( x1 < w->BorderLeft ) 
  437.    {
  438.       if ( x2 < w->BorderLeft ) 
  439.          return  ;
  440.       y1 = y1 +      ( double ) ( y2 - y1 )
  441.                   /  ( x2 - x1 )
  442.                   *  ( w->BorderLeft - x1 )  ;
  443.       x1 = w->BorderLeft  ;
  444.    }
  445.    else if ( x1 > ( w->Width - w->BorderRight ) )
  446.    {
  447.       if ( x2 >  ( w->Width - w->BorderRight ) )
  448.          return  ;
  449.       y1 = y1 +      ( double ) ( y2 - y1 )
  450.                   /  ( x2 - x1 )
  451.                   *  ( w->Width - w->BorderRight - x1 )  ;
  452.       x1 = w->Width - w->BorderRight  ;
  453.    }
  454.  
  455.    if ( y1 < w->BorderTop )
  456.    {
  457.       if ( y2 < w->BorderTop )
  458.          return  ;
  459.       x1 = x1 +      ( double ) ( x2 - x1 )
  460.                   /  ( y2 - y1 )
  461.                   *  ( w->BorderTop - y1 )  ;
  462.       y1 = w->BorderTop  ;
  463.       if (     ( x1 < w->BorderLeft ) 
  464.             || ( x1 > ( w->Width - w->BorderRight ) ) )
  465.          return  ;
  466.    }
  467.    else if ( y1 > ( w->Height - w->BorderBottom ) )
  468.    {
  469.       if ( y2 > ( w->Height - w->BorderBottom ) )
  470.          return  ;
  471.       x1 = x1 +      ( double ) ( x2 - x1 )
  472.                   /  ( y2 - y1 )
  473.                   *  ( w->Height - w->BorderBottom - y1 )  ;
  474.       y1 = w->Height - w->BorderBottom  ;
  475.       if (     ( x1 < w->BorderLeft ) 
  476.             || ( x1 > ( w->Width - w->BorderRight ) ) )
  477.          return  ;
  478.    }
  479.  
  480.    if ( x2 < w->BorderLeft ) 
  481.    {
  482.       y2 = y2 +      ( double ) ( y1 - y2 )
  483.                   /  ( x1 - x2 )
  484.                   *  ( w->BorderLeft - x2 )  ;
  485.       x2 = w->BorderLeft  ;
  486.    }
  487.    else if ( x2 > ( w->Width - w->BorderRight ) )
  488.    {
  489.       y2 = y2 +      ( double ) ( y1 - y2 )
  490.                   /  ( x1 - x2 )
  491.                   *  ( w->Width - w->BorderRight - x2 )  ;
  492.       x2 = w->Width - w->BorderRight  ;
  493.    }
  494.  
  495.    if ( y2 < w->BorderTop )
  496.    {
  497.       x2 = x2 +      ( double ) ( x1 - x2 )
  498.                   /  ( y1 - y2 )
  499.                   *  ( w->BorderTop - y2 )  ;
  500.       y2 = w->BorderTop  ;
  501.    }
  502.    else if ( y2 > ( w->Height - w->BorderBottom ) )
  503.    {
  504.       x2 = x2 +      ( double ) ( x1 - x2 )
  505.                   /  ( y1 - y2 )
  506.                   *  ( w->Height - w->BorderBottom - y2 )  ;
  507.       y2 = w->Height - w->BorderBottom  ;
  508.    }
  509.  
  510.    Move( w->RPort , x1 , y1 )  ;
  511.    Draw( w->RPort , x2 , y2 )  ;
  512.  }
  513.  
  514.  
  515.  void interface()
  516.  {
  517.    struct FileHandle    *fh  ;
  518.    struct filedata      *fd  ;
  519.    long        i , s  ;
  520.    struct dv   tv , vv  ;
  521.    double      x , y  ;
  522.    char        *p  ;
  523.  
  524.    if ( control )
  525.    {
  526.       while ( mes = GetMsg( control->UserPort ) )
  527.       {
  528.          readmes()  ;
  529.          switch ( class )
  530.          {
  531.          case MENUPICK :
  532.             handelmenu()  ;
  533.             break   ;
  534.          case GADGETUP :
  535.             if (        ( iadd->GadgetID < 20 )
  536.                      && (     g.objects[ iadd->GadgetID ].flags
  537.                            || ( g.awaiting == NEWPOSITION )
  538.                            || ( g.awaiting == NEWMASS )
  539.                            || ( g.awaiting == NEWCREATE )
  540.                            || ( g.awaiting == NEWVELOCITY ) ) )
  541.             {
  542.                Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) )  ;
  543.                Text( control->RPort , "  " , 2 )  ;
  544.  
  545.                g.objectnum = iadd->GadgetID  ;
  546.  
  547.                Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) )  ;
  548.                Text( control->RPort , "<-" , 2 )  ;
  549.  
  550.                setstrings()  ;
  551.  
  552.                if ( g.follow )
  553.                   resetdisplay()  ;
  554.             }
  555.             else
  556.             {
  557.                switch ( iadd->GadgetID )
  558.                {
  559.                case 20 :
  560.                   g.awaiting = NEWPOSITION  ;
  561.                   screentitle( NEWPOSITION )  ;
  562.                   break  ;
  563.                case 21 :
  564.                   g.awaiting = NEWVELOCITY  ;
  565.                   screentitle( NEWVELOCITY )  ;
  566.                   break  ;
  567.                case 22 :
  568.                   g.awaiting = NEWMASS  ;
  569.                   screentitle( NEWMASS )  ;
  570.                   break  ;
  571.                case 23 : /* delete */
  572.                   deleteobject( g.objectnum )  ;
  573.                   resetdisplay()  ;
  574.                   break  ;
  575.                case 24 : /* zero M */
  576.                   for ( tv = zerodv , x = 0.0 , i = 0 ; i < 20 ; i ++ )
  577.                   {
  578.                      if ( g.objects[ i ].flags && g.objects[ i ].mass )
  579.                      {
  580.                         scaledv(    &g.objects[ i ].velocity ,
  581.                                     &g.objects[ i ].mass ,
  582.                                     &vv )  ;
  583.                         adddv( &tv , &vv , &tv )  ;
  584.                         x = x + g.objects[ i ].mass  ;
  585.                      }
  586.                   }
  587.                   if ( x )
  588.                   {
  589.                      x = 1 / x  ;
  590.                      scaledv( &tv , &x , &tv )  ;
  591.                      for ( i = 0 ; i < 20 ; i ++ )
  592.                      {
  593.                         if ( g.objects[ i ].flags )
  594.                         {
  595.                            subdv(   &g.objects[ i ].velocity ,
  596.                                     &tv ,
  597.                                     &g.objects[ i ].velocity )  ;
  598.                         }
  599.                      }
  600.                   }
  601.                   set()  ;
  602.                   break  ;
  603.                case 25 :
  604.                   if ( g.awaiting > 1 )
  605.                   {
  606.                      g.awaiting = 0  ;
  607.                      resetdisplay()  ;
  608.                   }
  609.                   g.awaiting = 0  ;
  610.                   screentitle( 0 )  ;
  611.                   g.stopflag = 0  ;
  612.                   break  ;
  613.                case 26 :        /*  load  */
  614.                   Move( control->RPort , 200 , 62 )  ;
  615.                   p = AllocMem( 4700 , MEMF_CHIP |MEMF_CLEAR )  ;
  616.                   s = 1  ;
  617.                   if ( p )
  618.                   {
  619.                      fh = Open( filename , MODE_OLDFILE )  ;
  620.                      if ( fh )
  621.                      {
  622.                         ScreenToFront( screen )  ;
  623.  
  624.                         Text( control->RPort , 
  625.                                  "Loading file                 " , 29 )  ;
  626.                         fd = ( struct filedata * ) p  ;
  627.                         i = Read( fh , p , 4700 )  ;
  628.                         if ( i == 4700 )
  629.                         {
  630.                            for ( i = 0 ; i < 12 ; i ++ )
  631.                               if ( fd->tag[ i ] != g.tag[ i ] )
  632.                                  i = 20  ;
  633.                            if ( i < 20 )
  634.                            {
  635.                               s = g.stopflag  ;
  636.                               g = *fd  ;
  637.                               for ( i = 0 ; i < 20 ; i ++ )
  638.                               {
  639.                                  Move(    control->RPort ,
  640.                                           48 , 21 + ( i * 14 ) )  ;
  641.                                  if ( g.objects[ i ].flags )
  642.                                     Text( control->RPort , "*   " , 4 )  ;
  643.                                  else
  644.                                     Text( control->RPort , "    " , 4 )  ;
  645.                               }
  646.                               Move(    control->RPort ,
  647.                                        58 , 21 + ( g.objectnum * 14 ) )  ;
  648.                               Text( control->RPort , "<-" , 2 )  ;
  649.  
  650.                               screentitle( g.awaiting )  ;
  651.                               setstrings()  ;
  652.                               resetdisplay()  ;
  653.  
  654.                               Delay( 100 )  ;
  655.                               Move( control->RPort , 200 , 62 )  ;
  656.                               Text( control->RPort , 
  657.                                  "                             " , 29 )  ;
  658.                            }
  659.                            else
  660.                            {
  661.                               Move( control->RPort , 200 , 62 )  ;
  662.                               Text( control->RPort ,          
  663.                                  "ERROR Not a Gravity Well file" , 29 )  ;
  664.                            }
  665.                         }
  666.                         else
  667.                         {
  668.                            Move( control->RPort , 200 , 62 )  ;
  669.                            Text( control->RPort , 
  670.                                  "ERROR  While reading file    " , 29 )  ;
  671.                         }
  672.  
  673.                         Close( fh ) ;
  674.                      }
  675.                      else
  676.                         Text( control->RPort , 
  677.                                  "ERROR  Could not open file   " , 29 )  ;
  678.  
  679.                      ScreenToFront( screen )  ;
  680.                      FreeMem( p , 4700 )  ;
  681.                   }
  682.                   else
  683.                      Text( control->RPort , 
  684.                                  "ERROR  Out of memory         " , 29 )  ;
  685.  
  686.                   if ( g.stopflag && ( ! s ) )
  687.                      stoploop()  ;
  688.  
  689.                   break  ;
  690.                case 27 :        /*  save  */
  691.                   Move( control->RPort , 200 , 62 )  ;
  692.                   p = AllocMem( 4700 , MEMF_CHIP |MEMF_CLEAR )  ;
  693.                   if ( p )
  694.                   {
  695.                      fh = Open( filename , MODE_NEWFILE )  ;
  696.                      if ( fh )
  697.                      {
  698.                         ScreenToFront( screen )  ;
  699.                         Text( control->RPort ,
  700.                               "Saving file                  " , 29 )  ;
  701.                         Move( control->RPort , 200 , 62 )  ;
  702.                         fd = ( struct filedata * ) p  ;
  703.                         *fd = g  ;
  704.                         i = Write( fh , p , 4700 )  ;
  705.                         if ( i == 4700 )
  706.                         {
  707.                            Delay( 100 )  ;
  708.                            Text( control->RPort , 
  709.                               "                             " , 29 )  ;
  710.                         }
  711.                         else
  712.                            Text( control->RPort , 
  713.                               "ERROR  While writing file    " , 29 )  ;
  714.                           
  715.                         Close( fh ) ;
  716.                      }
  717.                      else
  718.                         Text( control->RPort ,
  719.                               "ERROR  Could not open file   " , 29 )  ;
  720.  
  721.                      ScreenToFront( screen )  ;
  722.                      FreeMem( p , 4700 )  ;
  723.                   }
  724.                   else
  725.                      Text( control->RPort ,
  726.                               "ERROR  Out of memory         " , 29 )  ;
  727.  
  728.                   break  ;
  729.                case 28 :
  730.                   for ( i = 0 ; i < 20 ; i ++ )
  731.                      deleteobject( i )  ;
  732.                   g.elapsedtime = 0.0  ;
  733.                   g.timestep = 0.01  ;
  734.                   g.magic = 100.0  ;
  735.                   g.scale = 0.5  ;
  736.                   g.trailson = 1  ;
  737.                   g.follow = 0  ;
  738.                   g.viewbasis = refobv  ;
  739.                   g.viewoffset = zerodv  ;
  740.                   g.filecomment1[ 0 ] = 0  ;
  741.                   g.filecomment2[ 0 ] = 0  ;
  742.                   setstrings()  ;
  743.                   resetdisplay()  ;
  744.                   if ( ! g.stopflag )
  745.                   {
  746.                      g.stopflag = 1  ;
  747.                      stoploop()  ;
  748.                   }
  749.                   break  ;
  750.                case 29 :
  751.                   g.awaiting = NEWCREATE  ;
  752.                   screentitle( NEWCREATE )  ;
  753.                   break  ;
  754.                case 30 :
  755.                   create()  ;
  756.  
  757.                   g.timestep = atof( &numberbuff[ 0 ][ 0 ] )  ;
  758.                   g.magic = atof( &numberbuff[ 1 ][ 0 ] )  ;
  759.  
  760.                   g.objects[ g.objectnum ].mass =
  761.                               atof( &numberbuff[ 2 ][ 0 ] )  ;
  762.                   g.objects[ g.objectnum ].radius =
  763.                               atof( &numberbuff[ 3 ][ 0 ] )  ;
  764.  
  765.                   g.objects[ g.objectnum ].position.x =
  766.                               atof( &numberbuff[ 4 ][ 0 ] )  ;
  767.                   g.objects[ g.objectnum ].position.y =
  768.                               atof( &numberbuff[ 6 ][ 0 ] )  ;
  769.                   g.objects[ g.objectnum ].position.z =
  770.                               atof( &numberbuff[ 8 ][ 0 ] )  ;
  771.  
  772.                   g.objects[ g.objectnum ].velocity.x =
  773.                               atof( &numberbuff[ 5 ][ 0 ] )  ;
  774.                   g.objects[ g.objectnum ].velocity.y =
  775.                               atof( &numberbuff[ 7 ][ 0 ] )  ;
  776.                   g.objects[ g.objectnum ].velocity.z =
  777.                               atof( &numberbuff[ 9 ][ 0 ] )  ;
  778.  
  779.                   set()  ;
  780.                   setstrings()  ;
  781.                   resetdisplay()  ;
  782.  
  783.                   break  ;
  784.                case 35 :
  785.                   g.timestep = atof( &numberbuff[ 0 ][ 0 ] )  ;
  786.                   p = gcvt( g.timestep , DBL_DIG , &numberbuff[ 0 ][ 0 ] )  ;
  787.                   RefreshGadgets( &controlgadg[ 31 ] , control , NULL )  ;
  788.                   break  ;
  789.                case 36 :
  790.                   g.magic = atof( &numberbuff[ 1 ][ 0 ] )  ;
  791.                   p = gcvt( g.magic , DBL_DIG , &numberbuff[ 1 ][ 0 ] )  ;
  792.                   RefreshGadgets( &controlgadg[ 31 ] , control , NULL )  ;
  793.                   break  ;
  794.                }
  795.             }
  796.  
  797.             if ( g.awaiting > 1 )
  798.             {
  799.                g.follow = 0  ;
  800.                resetdisplay()  ;
  801.                if ( ! g.stopflag )
  802.                {
  803.                   g.stopflag = 1  ;
  804.                   stoploop()  ;
  805.                }
  806.             }
  807.             break   ;
  808.          }
  809.       }
  810.    }
  811.    if ( viewcontrol )
  812.    {
  813.       while ( mes = GetMsg( viewcontrol->UserPort ) )
  814.       {
  815.          readmes()  ;
  816.          switch ( class )
  817.          {
  818.          case MENUPICK :
  819.             handelmenu()  ;
  820.             break  ;
  821.          case CLOSEWINDOW :
  822.             ClearMenuStrip( viewcontrol )  ;
  823.             viewcontrolnw.LeftEdge = viewcontrol->LeftEdge  ;
  824.             viewcontrolnw.TopEdge = viewcontrol->TopEdge  ;
  825.             CloseWindow( viewcontrol )  ;
  826.             viewcontrol = NULL  ;
  827.             break  ;
  828.          case GADGETUP :
  829.             switch ( iadd->GadgetID )
  830.             {
  831.             case 0 :
  832.                rotatedvpair10( &g.viewbasis.j , &g.viewbasis.i )  ;
  833.                break  ;
  834.             case 1 :
  835.                rotatedvpair10( &g.viewbasis.i , &g.viewbasis.j )  ;
  836.                break  ;
  837.             case 2 :
  838.                rotatedvpair10( &g.viewbasis.i , &g.viewbasis.k )  ;
  839.                break  ;
  840.             case 3 :
  841.                rotatedvpair10( &g.viewbasis.k , &g.viewbasis.i )  ;
  842.                break  ;
  843.             case 4 :
  844.                rotatedvpair10( &g.viewbasis.k , &g.viewbasis.j )  ;
  845.                break  ;
  846.             case 5 :
  847.                rotatedvpair10( &g.viewbasis.j , &g.viewbasis.k )  ;
  848.                break  ;
  849.             case 6 :
  850.                g.viewbasis = refobv  ;
  851.                g.unviewbasis = refobv  ;
  852.                break  ;
  853.             case 7 :
  854.                g.scale = g.scale * 1.6  ;
  855.                p = gcvt( g.scale , DBL_DIG , &ettext[ 0 ] )  ;
  856.                Move( control->RPort , 234 , 197 )  ;
  857.                Text( control->RPort ,  &ettext[ 0 ] ,
  858.                                        strlen( &ettext[ 0 ] ) )  ;
  859.                Text( control->RPort , "                    " , 20 )  ;
  860.                break  ;
  861.             case 8 :
  862.                g.scale = g.scale * 0.625  ;
  863.                p = gcvt( g.scale , DBL_DIG , &ettext[ 0 ] )  ;
  864.                Move( control->RPort , 234 , 197 )  ;
  865.                Text( control->RPort ,  &ettext[ 0 ] ,
  866.                                        strlen( &ettext[ 0 ] ) )  ;
  867.                Text( control->RPort , "                    " , 20 )  ;
  868.                break  ;
  869.             case 9 :
  870.                if ( g.trailson )
  871.                {
  872.                   g.trailson = 0  ;
  873.                   resetdisplay()  ;
  874.                }
  875.                else
  876.                g.trailson = 1  ;
  877.                break  ;
  878.             case 10 :
  879.                if ( g.awaiting == NEWCENTER )
  880.                {
  881.                   screentitle( 0 )  ;
  882.                   g.awaiting = 0  ;
  883.                }
  884.                else
  885.                {
  886.                   if ( g.follow )
  887.                   {
  888.                      g.follow = 0  ;
  889.                      resetdisplay()  ;
  890.                   }
  891.                   else if ( g.awaiting )
  892.                      resetdisplay()  ;
  893.                   screentitle( NEWCENTER )  ;
  894.                   g.awaiting = NEWCENTER  ;
  895.                }
  896.                break  ;
  897.             case 11 :
  898.                g.follow = ( g.follow ) ? 0 : 1  ;
  899.                break  ;
  900.             }
  901.             if ( iadd->GadgetID != 10 )
  902.             {
  903.                if ( g.awaiting == NEWCENTER )
  904.                {
  905.                   screentitle( 0 )  ;
  906.                   g.awaiting = 0  ;
  907.                }
  908.                resetdisplay()  ;
  909.             }
  910.             if ( iadd->GadgetID < 6 )
  911.             {
  912.                basis( &refobv.i , &g.viewbasis , &g.unviewbasis.i )  ;
  913.                basis( &refobv.j , &g.viewbasis , &g.unviewbasis.j )  ;
  914.                basis( &refobv.k , &g.viewbasis , &g.unviewbasis.k )  ;
  915.             }
  916.             break  ;
  917.          }
  918.          if ( ! viewcontrol )
  919.             break  ;
  920.       }
  921.    }
  922.    if ( mainview )
  923.    {
  924.       while ( mes = GetMsg( mainview->UserPort ) )
  925.       {
  926.          readmes()  ;
  927.          switch ( class )
  928.          {
  929.          case MENUPICK :
  930.             handelmenu()  ;
  931.             break  ;
  932.          case NEWSIZE :
  933.             blankwindow( mainview )  ;
  934.             setupdisplay( mainview )  ;
  935.             break  ;
  936.          case CLOSEWINDOW :
  937.             ClearMenuStrip( mainview )  ;
  938.             mainviewnw.LeftEdge = mainview->LeftEdge  ;
  939.             mainviewnw.TopEdge = mainview->TopEdge  ;
  940.             mainviewnw.Width = mainview->Width  ;
  941.             mainviewnw.Height = mainview->Height  ;
  942.             CloseWindow( mainview )  ;
  943.             mainview = NULL  ;
  944.             break  ;
  945.          case MOUSEBUTTONS :
  946.             if ( code == SELECTDOWN )
  947.             {
  948.                switch ( g.awaiting )
  949.                {
  950.                case NEWCENTER :
  951.                   g.viewoffset.x =  g.viewoffset.x
  952.                                  -  (     (     mousex
  953.                                              -  ( mainview->Width >> 1 ) )
  954.                                        /  ( g.scale * 200.0 ) )  ;
  955.                   g.viewoffset.y =  g.viewoffset.y
  956.                                  +  (     (     mousey
  957.                                              -  ( mainview->Height >> 1 ) )
  958.                                        /  ( g.scale * 177.0 ) )  ;
  959.                   resetdisplay()  ;
  960.                   break  ;
  961.                case NEWPOSITION :
  962.                   create()  ;
  963.                   basis(   &g.objects[ g.objectnum ].position ,
  964.                            &g.viewbasis ,
  965.                            &tv )  ;
  966.                   do
  967.                   {
  968.                      tv.x =      -g.viewoffset.x
  969.                               +  (     (     mainview->MouseX 
  970.                                           -  ( mainview->Width >> 1 ) )
  971.                                     /  ( g.scale * 200.0 ) )  ;
  972.                      tv.y =      -g.viewoffset.y
  973.                               -  (     (     mainview->MouseY 
  974.                                           -  ( mainview->Height >> 1 ) )
  975.                                     /  ( g.scale * 177.0 ) )  ;
  976.                      basis(   &tv ,
  977.                               &g.unviewbasis ,
  978.                               &g.objects[ g.objectnum ].position )  ; 
  979.                      resetdisplay()  ;
  980.                      Delay( 1 )  ;
  981.                      if ( mes = GetMsg( mainview->UserPort ) )
  982.                         readmes()  ;
  983.                   } while (      ( class != MOUSEBUTTONS ) 
  984.                               || ( code != SELECTUP ) ) ;
  985.                   g.objects[ g.objectnum ].oldpos = 
  986.                              g.objects[ g.objectnum ].position  ;
  987.                   set()  ;
  988.                   break  ;
  989.                case NEWVELOCITY :
  990.                   create()  ;
  991.                   adddv(   &g.objects[ g.objectnum ].position ,
  992.                            &g.objects[ g.objectnum ].velocity ,
  993.                            &vv )  ;
  994.                   basis(   &vv ,
  995.                            &g.viewbasis ,
  996.                            &tv )  ; 
  997.                   do
  998.                   {
  999.                      tv.x =      -g.viewoffset.x
  1000.                               +  (     (     mainview->MouseX 
  1001.                                           -  ( mainview->Width >> 1 ) )
  1002.                                     /  ( g.scale * 200.0 ) )  ;
  1003.                      tv.y =      -g.viewoffset.y
  1004.                               -  (     (     mainview->MouseY 
  1005.                                           -  ( mainview->Height >> 1 ) )
  1006.                                     /  ( g.scale * 177.0 ) )  ;
  1007.                      basis(   &tv ,
  1008.                               &g.unviewbasis ,
  1009.                               &vv )  ; 
  1010.                      subdv(   &vv ,
  1011.                               &g.objects[ g.objectnum ].position ,
  1012.                               &g.objects[ g.objectnum ].velocity )  ; 
  1013.                      resetdisplay()  ;
  1014.                      Delay( 1 )  ;
  1015.                      if ( mes = GetMsg( mainview->UserPort ) )
  1016.                         readmes()  ;
  1017.                   } while (      ( class != MOUSEBUTTONS ) 
  1018.                               || ( code != SELECTUP ) ) ;
  1019.                   set()  ;
  1020.                   break  ;
  1021.                case NEWMASS :
  1022.                   create()  ;
  1023.                   basis(   &g.objects[ g.objectnum ].position ,
  1024.                            &g.viewbasis ,
  1025.                            &tv )  ; 
  1026.                   do
  1027.                   {
  1028.                      x =      -g.viewoffset.x
  1029.                            +  (     (     mainview->MouseX 
  1030.                                        -  ( mainview->Width >> 1 ) )
  1031.                                  /  ( g.scale * 200.0 ) )  ;
  1032.                      y =      -g.viewoffset.y
  1033.                            -  (     (     mainview->MouseY 
  1034.                                           -  ( mainview->Height >> 1 ) )
  1035.                                     /  ( g.scale * 177.0 ) )  ;
  1036.                      x = x - tv.x  ;
  1037.                      y = y - tv.y  ;
  1038.                      g.objects[ g.objectnum ].mass = sqrt( x * x + y * y )  ;
  1039.                      resetdisplay()  ;
  1040.                      Delay( 1 )  ;
  1041.                      if ( mes = GetMsg( mainview->UserPort ) )
  1042.                         readmes()  ;
  1043.                   } while (      ( class != MOUSEBUTTONS )
  1044.                               || ( code != SELECTUP ) ) ;
  1045.                   set()  ;
  1046.                   break  ;
  1047.                }
  1048.             }
  1049.             break  ;
  1050.          }
  1051.          if ( ! mainview )
  1052.             break  ;
  1053.       }
  1054.    }
  1055.    if ( topview )
  1056.    {
  1057.       while ( mes = GetMsg( topview->UserPort ) )
  1058.       {
  1059.          readmes()  ;
  1060.          switch ( class )
  1061.          {
  1062.          case MENUPICK :
  1063.             handelmenu()  ;
  1064.             break  ;
  1065.          case NEWSIZE :
  1066.             blankwindow( topview )  ;
  1067.             setupdisplay( topview )  ;
  1068.             break  ;
  1069.          case CLOSEWINDOW :
  1070.             ClearMenuStrip( topview )  ;
  1071.             topviewnw.LeftEdge = topview->LeftEdge  ;
  1072.             topviewnw.TopEdge = topview->TopEdge  ;
  1073.             topviewnw.Width = topview->Width  ;
  1074.             topviewnw.Height = topview->Height  ;
  1075.             CloseWindow( topview )  ;
  1076.             topview = NULL  ;
  1077.             break  ;
  1078.          case MOUSEBUTTONS :
  1079.             if ( code == SELECTDOWN )
  1080.             {
  1081.                switch ( g.awaiting )
  1082.                {
  1083.                case NEWCENTER :
  1084.                   g.viewoffset.x =  g.viewoffset.x
  1085.                                  -  (     (     mousex 
  1086.                                              -  ( topview->Width >> 1 ) )
  1087.                                        /  ( g.scale * 200.0 ) )  ;
  1088.                   g.viewoffset.z =  g.viewoffset.z
  1089.                                  -  (     (     mousey
  1090.                                              -  ( topview->Height >> 1 ) )
  1091.                                        /  ( g.scale * 177.0 ) )  ;
  1092.                   resetdisplay()  ;
  1093.                   break  ;
  1094.                case NEWPOSITION :
  1095.                   create()  ;
  1096.                   basis(   &g.objects[ g.objectnum ].position ,
  1097.                            &g.viewbasis ,
  1098.                            &tv )  ; 
  1099.                   do
  1100.                   {
  1101.                      tv.x =      -g.viewoffset.x
  1102.                               +  (     (     topview->MouseX 
  1103.                                           -  ( topview->Width >> 1 ) )
  1104.                                     /  ( g.scale * 200.0 ) )  ;
  1105.                      tv.z =      -g.viewoffset.z
  1106.                               +  (     (     topview->MouseY 
  1107.                                           -  ( topview->Height >> 1 ) )
  1108.                                     /  ( g.scale * 177.0 ) )  ;
  1109.                      basis(   &tv ,
  1110.                               &g.unviewbasis ,
  1111.                               &g.objects[ g.objectnum ].position )  ;
  1112.                      resetdisplay()  ;
  1113.                      Delay( 1 )  ;
  1114.                      if ( mes = GetMsg( topview->UserPort ) )
  1115.                         readmes()  ;
  1116.                   } while (      ( class != MOUSEBUTTONS )
  1117.                               || ( code != SELECTUP ) ) ;
  1118.                   g.objects[ g.objectnum ].oldpos =
  1119.                              g.objects[ g.objectnum ].position  ;
  1120.                   set()  ;
  1121.                   break  ;
  1122.                case NEWVELOCITY :
  1123.                   create()  ;
  1124.                   adddv(   &g.objects[ g.objectnum ].position ,
  1125.                            &g.objects[ g.objectnum ].velocity ,
  1126.                            &vv )  ;
  1127.                   basis(   &vv ,
  1128.                            &g.viewbasis ,
  1129.                            &tv )  ;
  1130.                   do
  1131.                   {
  1132.                      tv.x =      -g.viewoffset.x
  1133.                               +  (     (     topview->MouseX 
  1134.                                           -  ( topview->Width >> 1 ) )
  1135.                                     /  ( g.scale * 200.0 ) )  ;
  1136.                      tv.z =      -g.viewoffset.z
  1137.                               +  (     (     topview->MouseY 
  1138.                                           -  ( topview->Height >> 1 ) )
  1139.                                     /  ( g.scale * 177.0 ) )  ;
  1140.                      basis(   &tv ,
  1141.                               &g.unviewbasis ,
  1142.                               &vv )  ; 
  1143.                      subdv(   &vv ,
  1144.                               &g.objects[ g.objectnum ].position ,
  1145.                               &g.objects[ g.objectnum ].velocity )  ;
  1146.                      resetdisplay()  ;
  1147.                      Delay( 1 )  ;
  1148.                      if ( mes = GetMsg( topview->UserPort ) )
  1149.                         readmes()  ;
  1150.                   } while (      ( class != MOUSEBUTTONS )
  1151.                               || ( code != SELECTUP ) ) ;
  1152.                   set()  ;
  1153.                   break  ;
  1154.                case NEWMASS :
  1155.                   create()  ;
  1156.                   basis(   &g.objects[ g.objectnum ].position ,
  1157.                            &g.viewbasis ,
  1158.                            &tv )  ;
  1159.                   do
  1160.                   {
  1161.                      x =      -g.viewoffset.x
  1162.                            +  (     (     topview->MouseX
  1163.                                        -  ( topview->Width >> 1 ) )
  1164.                                  /  ( g.scale * 200.0 ) )  ;
  1165.                      y =      -g.viewoffset.z
  1166.                            +  (     (     topview->MouseY
  1167.                                        -  ( topview->Height >> 1 ) )
  1168.                                  /  ( g.scale * 177.0 ) )  ;
  1169.                      x = x - tv.x  ;
  1170.                      y = y - tv.z  ;
  1171.                      g.objects[ g.objectnum ].mass = sqrt( x * x + y * y )  ;
  1172.                      resetdisplay()  ;
  1173.                      Delay( 1 )  ;
  1174.                      if ( mes = GetMsg( topview->UserPort ) )
  1175.                         readmes()  ;
  1176.                   } while (      ( class != MOUSEBUTTONS )
  1177.                               || ( code != SELECTUP ) ) ;
  1178.                   set()  ;
  1179.                   break  ;
  1180.                }
  1181.             }
  1182.             break  ;
  1183.          }
  1184.          if ( ! topview )
  1185.             break  ;
  1186.       }
  1187.    }
  1188.    if ( rightview )
  1189.    {
  1190.       while ( mes = GetMsg( rightview->UserPort ) )
  1191.       {
  1192.          readmes()  ;
  1193.          switch ( class )
  1194.          {
  1195.          case MENUPICK :
  1196.             handelmenu()  ;
  1197.             break  ;
  1198.          case NEWSIZE :
  1199.             blankwindow( rightview )  ;
  1200.             setupdisplay( rightview )  ;
  1201.             break  ;
  1202.          case CLOSEWINDOW :
  1203.             ClearMenuStrip( rightview )  ;
  1204.             rightviewnw.LeftEdge = rightview->LeftEdge  ;
  1205.             rightviewnw.TopEdge = rightview->TopEdge  ;
  1206.             rightviewnw.Width = rightview->Width  ;
  1207.             rightviewnw.Height = rightview->Height  ;
  1208.             CloseWindow( rightview )  ;
  1209.             rightview = NULL  ;
  1210.             break  ;
  1211.          case MOUSEBUTTONS :
  1212.             if ( code == SELECTDOWN )
  1213.             {
  1214.                switch ( g.awaiting )
  1215.                {
  1216.                case NEWCENTER :
  1217.                   g.viewoffset.z =  g.viewoffset.z
  1218.                                  +  (     (     mousex 
  1219.                                              -  ( rightview->Width >> 1 ) )
  1220.                                        /  ( g.scale * 200.0 ) )  ;
  1221.                   g.viewoffset.y =  g.viewoffset.y
  1222.                                  +  (     (     mousey 
  1223.                                              -  ( rightview->Height >> 1 ) )
  1224.                                        /  ( g.scale * 177.0 ) )  ;
  1225.                   resetdisplay()  ;
  1226.                   break  ;
  1227.                case NEWPOSITION :
  1228.                   create()  ;
  1229.                   basis(   &g.objects[ g.objectnum ].position ,
  1230.                            &g.viewbasis ,
  1231.                            &tv )  ; 
  1232.                   do
  1233.                   {
  1234.                      tv.z =      -g.viewoffset.z
  1235.                               -  (     (     rightview->MouseX 
  1236.                                           -  ( rightview->Width >> 1 ) )
  1237.                                     /  ( g.scale * 200.0 ) )  ;
  1238.                      tv.y =      -g.viewoffset.y
  1239.                               -  (     (     rightview->MouseY 
  1240.                                           -  ( rightview->Height >> 1 ) )
  1241.                                     /  ( g.scale * 177.0 ) )  ;
  1242.                      basis(   &tv ,
  1243.                               &g.unviewbasis ,
  1244.                               &g.objects[ g.objectnum ].position )  ; 
  1245.                      resetdisplay()  ;
  1246.                      Delay( 1 )  ;
  1247.                      if ( mes = GetMsg( rightview->UserPort ) )
  1248.                         readmes()  ;
  1249.                   } while (      ( class != MOUSEBUTTONS ) 
  1250.                               || ( code != SELECTUP ) ) ;
  1251.                   g.objects[ g.objectnum ].oldpos = 
  1252.                              g.objects[ g.objectnum ].position  ;
  1253.                   set()  ;
  1254.                   break  ;
  1255.                case NEWVELOCITY :
  1256.                   create()  ;
  1257.                   adddv(   &g.objects[ g.objectnum ].position ,
  1258.                            &g.objects[ g.objectnum ].velocity ,
  1259.                            &vv )  ;
  1260.                   basis(   &vv ,
  1261.                            &g.viewbasis ,
  1262.                            &tv )  ;
  1263.                   do
  1264.                   {
  1265.                      tv.z =      -g.viewoffset.z
  1266.                               -  (     (     rightview->MouseX
  1267.                                           -  ( rightview->Width >> 1 ) )
  1268.                                     /  ( g.scale * 200.0 ) )  ;
  1269.                      tv.y =      -g.viewoffset.y
  1270.                               -  (     (     rightview->MouseY
  1271.                                           -  ( rightview->Height >> 1 ) )
  1272.                                     /  ( g.scale * 177.0 ) )  ;
  1273.                      basis(   &tv ,
  1274.                               &g.unviewbasis ,
  1275.                               &vv )  ; 
  1276.                      subdv(   &vv ,
  1277.                               &g.objects[ g.objectnum ].position ,
  1278.                               &g.objects[ g.objectnum ].velocity )  ;
  1279.                      resetdisplay()  ;
  1280.                      Delay( 1 )  ;
  1281.                      if ( mes = GetMsg( rightview->UserPort ) )
  1282.                         readmes()  ;
  1283.                   } while (      ( class != MOUSEBUTTONS )
  1284.                               || ( code != SELECTUP ) ) ;
  1285.                   set()  ;
  1286.                   break  ;
  1287.                case NEWMASS :
  1288.                   create()  ;
  1289.                   basis(   &g.objects[ g.objectnum ].position ,
  1290.                            &g.viewbasis ,
  1291.                            &tv )  ;
  1292.                   do
  1293.                   {
  1294.                      x =      -g.viewoffset.z
  1295.                            -  (     (     rightview->MouseX
  1296.                                        -  ( rightview->Width >> 1 ) )
  1297.                                  /  ( g.scale * 200.0 ) )  ;
  1298.                      y =      -g.viewoffset.y
  1299.                            -  (     (     rightview->MouseY
  1300.                                        -  ( rightview->Height >> 1 ) )
  1301.                                  /  ( g.scale * 177.0 ) )  ;
  1302.                      x = x - tv.z  ;
  1303.                      y = y - tv.y  ;
  1304.                      g.objects[ g.objectnum ].mass = sqrt( x * x + y * y )  ;
  1305.                      resetdisplay()  ;
  1306.                      Delay( 1 )  ;
  1307.                      if ( mes = GetMsg( rightview->UserPort ) )
  1308.                         readmes()  ;
  1309.                   } while (      ( class != MOUSEBUTTONS )
  1310.                               || ( code != SELECTUP ) ) ;
  1311.                   set()  ;
  1312.                   break  ;
  1313.                }
  1314.             }
  1315.             break  ;
  1316.          }
  1317.          if ( ! rightview )
  1318.             break  ;
  1319.       }
  1320.    }
  1321.    if (     ( g.awaiting != NEWPOSITION )
  1322.          && ( g.awaiting != NEWVELOCITY )
  1323.          && ( g.awaiting != NEWMASS )
  1324.          && ( g.awaiting != NEWCREATE )
  1325.          && ( ! g.objects[ g.objectnum ].flags ) )
  1326.    {
  1327.       for ( i = 0 ; ( ! g.objects[ i ].flags ) && ( i < 19 ) ; i ++ )
  1328.          ;
  1329.       if ( ( i == 19 ) && ( ! g.objects[ 19 ].flags ) )
  1330.          i = 0  ;
  1331.  
  1332.       Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) )  ;
  1333.       Text( control->RPort , "  " , 2 )  ;
  1334.  
  1335.       g.objectnum = i  ;
  1336.  
  1337.       Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) )  ;
  1338.       Text( control->RPort , "<-" , 2 )  ;
  1339.  
  1340.       setstrings()  ;
  1341.    }
  1342.  }
  1343.  
  1344.  
  1345.  void readmes()                                          
  1346.  {
  1347.    class = mes->Class  ;
  1348.    code = mes->Code  ;
  1349.    mousex = mes->MouseX  ;
  1350.    mousey = mes->MouseY  ;
  1351.    iadd = ( struct Gadget * ) mes->IAddress  ;
  1352.    ReplyMsg( mes )  ;
  1353.  }
  1354.  
  1355.  
  1356.  void handelmenu()
  1357.  {
  1358.    long     i  ;
  1359.  
  1360.    switch ( MENUNUM( code ) )
  1361.    {
  1362.    case 0 :
  1363.       if ( ITEMNUM( code ) == 0 )
  1364.          cleanup()  ;
  1365.       break  ;
  1366.    case 1 :
  1367.       switch ( ITEMNUM( code ) )
  1368.       {
  1369.       case 0 :
  1370.          openmainview()  ;
  1371.          break  ;
  1372.       case 1 :
  1373.          opentopview()  ;
  1374.          break  ;
  1375.       case 2 :
  1376.          openrightview()  ;
  1377.          break  ;
  1378.       case 3 :
  1379.          openviewcontrol()  ;
  1380.          break  ;
  1381.       case 4 :
  1382.          WindowToFront( control )  ;
  1383.          break  ;
  1384.       }
  1385.       break  ;
  1386.    case 2 :
  1387.       switch ( ITEMNUM( code ) )
  1388.       {
  1389.       case 0 :
  1390.          if ( g.awaiting > 1 )
  1391.          {
  1392.             g.awaiting = 0  ;
  1393.             resetdisplay()  ;
  1394.          }
  1395.          g.awaiting = 0  ;
  1396.          screentitle( 0 )  ;
  1397.          g.stopflag = 0  ;
  1398.          break  ;
  1399.       case 1 :
  1400.          if ( ! g.stopflag )
  1401.          {
  1402.             g.stopflag = 1  ;
  1403.             stoploop()  ;
  1404.          }
  1405.          break  ;
  1406.       case 2 :
  1407.          set()  ;
  1408.          break  ;
  1409.       case 3 :
  1410.          g.elapsedtime = 0  ;
  1411.          for ( i = 0 ; i < 20 ; i ++ )
  1412.          {
  1413.             g.objects[ i ].collision = 0  ;
  1414.             g.objects[ i ].mass = g.objects[ i ].startmass  ;
  1415.             g.objects[ i ].position = g.objects[ i ].startpos  ;
  1416.             g.objects[ i ].oldpos = g.objects[ i ].startpos  ;
  1417.             g.objects[ i ].velocity = g.objects[ i ].startvel  ;
  1418.          }
  1419.          resetdisplay()  ;
  1420.          break  ;
  1421.       }
  1422.       break  ;
  1423.    }
  1424.  }
  1425.  
  1426.  
  1427.  void stoploop()
  1428.  {
  1429.    ULONG    s  ;
  1430.  
  1431.    while ( g.stopflag )
  1432.    {
  1433.       s = 1 << control->UserPort->mp_SigBit  ;
  1434.       if ( viewcontrol )
  1435.          s |= 1 << viewcontrol->UserPort->mp_SigBit  ;
  1436.       if ( mainview )
  1437.          s |= 1 << mainview->UserPort->mp_SigBit  ;
  1438.       if ( topview )
  1439.          s |= 1 << topview->UserPort->mp_SigBit  ;
  1440.       if ( rightview )
  1441.          s |= 1 << rightview->UserPort->mp_SigBit  ;
  1442.       Wait( s )  ;
  1443.       interface()  ;
  1444.    }
  1445.  }
  1446.  
  1447.  
  1448.  void resetdisplay()
  1449.  {
  1450.    char  *p  ;
  1451.  
  1452.    blankwindow( mainview )  ;
  1453.    setupdisplay( mainview )  ;
  1454.    blankwindow( topview )  ;
  1455.    setupdisplay( topview )  ;
  1456.    blankwindow( rightview )  ;
  1457.    setupdisplay( rightview )  ;
  1458.  
  1459.    p = gcvt( g.elapsedtime , DBL_DIG , &ettext[ 0 ] )  ;
  1460.    Move( control->RPort , 234 , 211 )  ;
  1461.    Text( control->RPort , &ettext[ 0 ] , strlen( &ettext[ 0 ] ) )  ;
  1462.    Text( control->RPort , "                    " , 20 )  ;
  1463.  
  1464.    p = gcvt( g.scale , DBL_DIG , &ettext[ 0 ] )  ;
  1465.    Move( control->RPort , 234 , 197 )  ;
  1466.    Text( control->RPort ,  &ettext[ 0 ] , strlen( &ettext[ 0 ] ) )  ;
  1467.    Text( control->RPort , "                    " , 20 )  ;
  1468.  }
  1469.  
  1470.  
  1471.  void screentitle( n )  
  1472.    long  n  ;
  1473.  {
  1474.    SetWindowTitles( control , -1 , titletext[ n ] )  ;
  1475.    if ( viewcontrol )
  1476.       SetWindowTitles( viewcontrol , -1 , titletext[ n ] )  ;
  1477.    if ( mainview )
  1478.       SetWindowTitles( mainview , -1 , titletext[ n ] )  ;
  1479.    if ( topview )
  1480.       SetWindowTitles( topview , -1 , titletext[ n ] )  ;
  1481.    if ( rightview )
  1482.       SetWindowTitles( rightview , -1 , titletext[ n ] )  ;
  1483.  }
  1484.  
  1485.  
  1486.  void setupdisplay( w )
  1487.    struct Window  *w  ;
  1488.  {
  1489.    struct dv   np , vv ;
  1490.    long     xx , yy , tx , ty , ux , uy , i  ;
  1491.  
  1492.    if ( ! w )
  1493.       return  ;
  1494.  
  1495.    if ( g.awaiting > 1 )
  1496.    {
  1497.       basis( &g.objects[ g.objectnum ].position , &g.viewbasis , &np )  ;
  1498.       adddv( &np , &g.viewoffset , &np )  ;
  1499.       if ( w == mainview )
  1500.       {
  1501.          SetAPen( mainview->RPort , DOTPEN )  ;
  1502.          xx =     ( mainview->Width >> 1 )
  1503.                +  ( long ) ( g.scale * np.x * 200.0 )  ;
  1504.          yy =     ( mainview->Height >> 1 )
  1505.                -  ( long ) ( g.scale * np.y * 177.0 )  ;
  1506.          linelong( mainview , xx - 6 , yy , xx + 6 , yy )  ;
  1507.          linelong( mainview , xx , yy - 5 , xx , yy + 5 )  ;
  1508.          if ( g.awaiting == NEWVELOCITY )
  1509.          {
  1510.             SetAPen( mainview->RPort , LINEPEN )  ;
  1511.             for( i = 0 ; i < 20 ; i ++ )
  1512.             {
  1513.                if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) )
  1514.                {
  1515.                   basis( &g.objects[ i ].position , &g.viewbasis , &np )  ;
  1516.                   adddv( &np , &g.viewoffset , &np )  ;
  1517.                   xx =     ( mainview->Width >> 1 )
  1518.                         +  ( long ) ( g.scale * np.x * 200.0 )  ;
  1519.                   yy =     ( mainview->Height >> 1 )
  1520.                         -  ( long ) ( g.scale * np.y * 177.0 )  ;
  1521.                   adddv(   &g.objects[ i ].position ,
  1522.                            &g.objects[ i ].velocity , &np )  ;
  1523.                   basis( &np , &g.viewbasis , &vv )  ;
  1524.                   adddv( &vv , &g.viewoffset , &vv )  ;
  1525.                   tx =     ( mainview->Width >> 1 ) 
  1526.                         +  ( long ) ( g.scale * vv.x * 200.0 )  ;
  1527.                   ty =     ( mainview->Height >> 1 )
  1528.                         -  ( long ) ( g.scale * vv.y * 177.0 )  ;
  1529.                   linelong( mainview , xx , yy , tx , ty )  ;
  1530.                }
  1531.             }
  1532.          }
  1533.          else if ( g.awaiting == NEWMASS )
  1534.          {
  1535.             SetAPen( mainview->RPort , LINEPEN )  ;
  1536.             for( i = 0 ; i < 20 ; i ++ )
  1537.             {
  1538.                if (     ( g.objects[ i ].flags )
  1539.                      && ( g.objects[ i ].mass )
  1540.                      && ( ! g.objects[ i ].collision ) )
  1541.                {
  1542.                   basis( &g.objects[ i ].position , &g.viewbasis , &np )  ;
  1543.                   adddv( &np , &g.viewoffset , &np )  ;
  1544.                   xx =     ( mainview->Width >> 1 )
  1545.                         +  ( long ) ( g.scale * np.x * 200.0 )  ;
  1546.                   yy =     ( mainview->Height >> 1 )
  1547.                         -  ( long ) ( g.scale * np.y * 177.0 )  ;
  1548.                   tx = ( long ) ( g.scale * g.objects[ i ].mass * 200.0 )  ;
  1549.                   ty = ( long ) ( g.scale * g.objects[ i ].mass * 177.0 )  ;
  1550.                   ux = ( long ) ( g.scale * g.objects[ i ].mass * 80.0 )  ;
  1551.                   uy = ( long ) ( g.scale * g.objects[ i ].mass * 70.0 )  ;
  1552.                   linelong(   mainview ,
  1553.                               xx + ux , yy + ty , xx - ux , yy + ty )  ;
  1554.                   linelong(   mainview ,
  1555.                               xx - ux , yy + ty , xx - tx , yy + uy )  ;
  1556.                   linelong(   mainview ,
  1557.                               xx - tx , yy + uy , xx - tx , yy - uy )  ;
  1558.                   linelong(   mainview ,
  1559.                               xx - tx , yy - uy , xx - ux , yy - ty )  ;
  1560.                   linelong(   mainview ,
  1561.                               xx - ux , yy - ty , xx + ux , yy - ty )  ;
  1562.                   linelong(   mainview ,
  1563.                               xx + ux , yy - ty , xx + tx , yy - uy )  ;
  1564.                   linelong(   mainview ,
  1565.                               xx + tx , yy - uy , xx + tx , yy + uy )  ;
  1566.                   linelong(   mainview ,
  1567.                               xx + tx , yy + uy , xx + ux , yy + ty )  ;
  1568.                }
  1569.             }
  1570.          }
  1571.       }
  1572.       if ( w == topview )
  1573.       {
  1574.          SetAPen( topview->RPort , DOTPEN )  ;
  1575.          xx =     ( topview->Width >> 1 )
  1576.                +  ( long ) ( g.scale * np.x * 200.0 )  ;
  1577.          yy =     ( topview->Height >> 1 )
  1578.                -  ( long ) ( g.scale * -np.z * 177.0 )  ;
  1579.          linelong( topview , xx - 6 , yy , xx + 6 , yy )  ;
  1580.          linelong( topview , xx , yy - 5 , xx , yy + 5 )  ;
  1581.          if ( g.awaiting == NEWVELOCITY )
  1582.          {
  1583.             SetAPen( topview->RPort , LINEPEN )  ;
  1584.             for( i = 0 ; i < 20 ; i ++ )
  1585.             {
  1586.                if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) )
  1587.                {
  1588.                   basis( &g.objects[ i ].position , &g.viewbasis , &np )  ;
  1589.                   adddv( &np , &g.viewoffset , &np )  ;
  1590.                   xx =     ( topview->Width >> 1 )
  1591.                         +  ( long ) ( g.scale * np.x * 200.0 )  ;
  1592.                   yy =     ( topview->Height >> 1 )
  1593.                         -  ( long ) ( g.scale * -np.z * 177.0 )  ;
  1594.                   adddv(   &g.objects[ i ].position ,
  1595.                            &g.objects[ i ].velocity , &np )  ;
  1596.                   basis( &np , &g.viewbasis , &vv )  ;
  1597.                   adddv( &vv , &g.viewoffset , &vv )  ;
  1598.                   tx =     ( topview->Width >> 1 ) 
  1599.                         +  ( long ) ( g.scale * vv.x * 200.0 )  ;
  1600.                   ty =     ( topview->Height >> 1 )
  1601.                         -  ( long ) ( g.scale * -vv.z * 177.0 )  ;
  1602.                   linelong( topview , xx , yy , tx , ty )  ;
  1603.                }
  1604.             }
  1605.          }
  1606.          else if ( g.awaiting == NEWMASS )
  1607.          {
  1608.             SetAPen( topview->RPort , LINEPEN )  ;
  1609.             for( i = 0 ; i < 20 ; i ++ )
  1610.             {
  1611.                if (     ( g.objects[ i ].flags )
  1612.                      && ( g.objects[ i ].mass )
  1613.                      && ( ! g.objects[ i ].collision ) )
  1614.                {
  1615.                   basis( &g.objects[ i ].position , &g.viewbasis , &np )  ;
  1616.                   adddv( &np , &g.viewoffset , &np )  ;
  1617.                   xx =     ( topview->Width >> 1 )
  1618.                         +  ( long ) ( g.scale * np.x * 200.0 )  ;
  1619.                   yy =     ( topview->Height >> 1 )
  1620.                         -  ( long ) ( g.scale * -np.z * 177.0 )  ;
  1621.                   tx = ( long ) ( g.scale * g.objects[ i ].mass * 200.0 )  ;
  1622.                   ty = ( long ) ( g.scale * g.objects[ i ].mass * 177.0 )  ;
  1623.                   ux = ( long ) ( g.scale * g.objects[ i ].mass * 80.0 )  ;
  1624.                   uy = ( long ) ( g.scale * g.objects[ i ].mass * 70.0 )  ;
  1625.                   linelong(   topview ,
  1626.                               xx + ux , yy + ty , xx - ux , yy + ty )  ;
  1627.                   linelong(   topview ,
  1628.                               xx - ux , yy + ty , xx - tx , yy + uy )  ;
  1629.                   linelong(   topview ,
  1630.                               xx - tx , yy + uy , xx - tx , yy - uy )  ;
  1631.                   linelong(   topview ,
  1632.                               xx - tx , yy - uy , xx - ux , yy - ty )  ;
  1633.                   linelong(   topview ,
  1634.                               xx - ux , yy - ty , xx + ux , yy - ty )  ;
  1635.                   linelong(   topview ,
  1636.                               xx + ux , yy - ty , xx + tx , yy - uy )  ;
  1637.                   linelong(   topview ,
  1638.                               xx + tx , yy - uy , xx + tx , yy + uy )  ;
  1639.                   linelong(   topview ,
  1640.                               xx + tx , yy + uy , xx + ux , yy + ty )  ;
  1641.                }
  1642.             }
  1643.          }
  1644.       }
  1645.       if ( w == rightview )
  1646.       {
  1647.          SetAPen( rightview->RPort , DOTPEN )  ;
  1648.          xx =     ( rightview->Width >> 1 )
  1649.                +  ( long ) ( g.scale * -np.z * 200.0 )  ;
  1650.          yy =     ( rightview->Height >> 1 )
  1651.                -  ( long ) ( g.scale * np.y * 177.0 )  ;
  1652.          linelong( rightview , xx - 6 , yy , xx + 6 , yy )  ;
  1653.          linelong( rightview , xx , yy - 5 , xx , yy + 5 )  ;
  1654.          if ( g.awaiting == NEWVELOCITY )
  1655.          {
  1656.             SetAPen( rightview->RPort , LINEPEN )  ;
  1657.             for( i = 0 ; i < 20 ; i ++ )
  1658.             {
  1659.                if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) )
  1660.                {
  1661.                   basis( &g.objects[ i ].position , &g.viewbasis , &np )  ;
  1662.                   adddv( &np , &g.viewoffset , &np )  ;
  1663.                   xx =     ( rightview->Width >> 1 )
  1664.                         +  ( long ) ( g.scale * -np.z * 200.0 )  ;
  1665.                   yy =     ( rightview->Height >> 1 )
  1666.                         -  ( long ) ( g.scale * np.y * 177.0 )  ;
  1667.                   adddv(   &g.objects[ i ].position , 
  1668.                            &g.objects[ i ].velocity , &np )  ;
  1669.                   basis( &np , &g.viewbasis , &vv )  ; 
  1670.                   adddv( &vv , &g.viewoffset , &vv )  ;
  1671.                   tx =     ( rightview->Width >> 1 ) 
  1672.                         +  ( long ) ( g.scale * -vv.z * 200.0 )  ;
  1673.                   ty =     ( rightview->Height >> 1 )
  1674.                         -  ( long ) ( g.scale * vv.y * 177.0 )  ;
  1675.                   linelong( rightview , xx , yy , tx , ty )  ;
  1676.                }
  1677.             }
  1678.          }
  1679.          else if ( g.awaiting == NEWMASS )
  1680.          {
  1681.             SetAPen( rightview->RPort , LINEPEN )  ;
  1682.             for( i = 0 ; i < 20 ; i ++ )
  1683.             {
  1684.                if (     ( g.objects[ i ].flags )
  1685.                      && ( g.objects[ i ].mass )
  1686.                      && ( ! g.objects[ i ].collision ) )
  1687.                {
  1688.                   basis( &g.objects[ i ].position , &g.viewbasis , &np )  ;
  1689.                   adddv( &np , &g.viewoffset , &np )  ;
  1690.                   xx =     ( rightview->Width >> 1 )
  1691.                         +  ( long ) ( g.scale * -np.z * 200.0 )  ;
  1692.                   yy =     ( rightview->Height >> 1 )
  1693.                         -  ( long ) ( g.scale * np.y * 177.0 )  ;
  1694.                   tx = ( long ) ( g.scale * g.objects[ i ].mass * 200.0 )  ;
  1695.                   ty = ( long ) ( g.scale * g.objects[ i ].mass * 177.0 )  ;
  1696.                   ux = ( long ) ( g.scale * g.objects[ i ].mass * 80.0 )  ;
  1697.                   uy = ( long ) ( g.scale * g.objects[ i ].mass * 70.0 )  ;
  1698.                   linelong(   rightview ,
  1699.                               xx + ux , yy + ty , xx - ux , yy + ty )  ;
  1700.                   linelong(   rightview ,
  1701.                               xx - ux , yy + ty , xx - tx , yy + uy )  ;
  1702.                   linelong(   rightview ,
  1703.                               xx - tx , yy + uy , xx - tx , yy - uy )  ;
  1704.                   linelong(   rightview ,
  1705.                               xx - tx , yy - uy , xx - ux , yy - ty )  ;
  1706.                   linelong(   rightview ,
  1707.                               xx - ux , yy - ty , xx + ux , yy - ty )  ;
  1708.                   linelong(   rightview ,
  1709.                               xx + ux , yy - ty , xx + tx , yy - uy )  ;
  1710.                   linelong(   rightview ,
  1711.                               xx + tx , yy - uy , xx + tx , yy + uy )  ;
  1712.                   linelong(   rightview ,
  1713.                               xx + tx , yy + uy , xx + ux , yy + ty )  ;
  1714.                }
  1715.             }
  1716.          }
  1717.       }
  1718.    }
  1719.  
  1720.    for ( i = 0 ; i < 20 ; i ++ )
  1721.    {
  1722.       if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) )
  1723.       {
  1724.          if ( g.follow )
  1725.          {
  1726.             subdv(   &g.objects[ i ].position ,
  1727.                      &g.objects[ g.objectnum ].position , &vv )  ;
  1728.             basis( &vv , &g.viewbasis , &np )  ;
  1729.          }
  1730.          else
  1731.          {
  1732.             basis( &g.objects[ i ].position , &g.viewbasis , &np )  ;
  1733.             adddv( &np , &g.viewoffset , &np )  ;
  1734.          }
  1735.          SetAPen( w->RPort , DOTPEN )  ;
  1736.          if ( w == mainview )
  1737.             pixel( w , np.x , np.y )  ;
  1738.          if ( w == topview )
  1739.             pixel( w , np.x , -np.z )  ;
  1740.          if ( w == rightview )
  1741.             pixel( w , -np.z , np.y )  ;
  1742.       }
  1743.    }
  1744.  }
  1745.  
  1746.  
  1747.  void set()
  1748.  {
  1749.    long     i  ;
  1750.  
  1751.    g.elapsedtime = 0  ;
  1752.    for ( i = 0 ; i < 20 ; i ++ )
  1753.    {
  1754.       g.objects[ i ].startmass = g.objects[ i ].mass  ;
  1755.       g.objects[ i ].startpos = g.objects[ i ].position  ;
  1756.       g.objects[ i ].oldpos = g.objects[ i ].position  ;
  1757.       g.objects[ i ].startvel = g.objects[ i ].velocity  ;
  1758.       if ( g.objects[ i ].collision )
  1759.          deleteobject( i )  ;
  1760.    }
  1761.    setstrings()  ;
  1762.  }
  1763.  
  1764.  
  1765.  void create()
  1766.  {
  1767.    g.objects[ g.objectnum ].flags = 1  ;
  1768.    g.objects[ g.objectnum ].collision = 0  ;
  1769.    Move( control->RPort , 48 , 21 + ( g.objectnum * 14 ) )  ;
  1770.    Text( control->RPort , "*" , 1 )  ;
  1771.  }
  1772.  
  1773.  
  1774.  void setstrings()
  1775.  {
  1776.    char  *p  ;
  1777.  
  1778.    controlinfo[ 3 ].Buffer = &g.objects[ g.objectnum ].name[ 0 ]  ;
  1779.    p = gcvt(   g.timestep , DBL_DIG , &numberbuff[ 0 ][ 0 ] )  ;
  1780.    p = gcvt(   g.magic , DBL_DIG , &numberbuff[ 1 ][ 0 ] )  ;
  1781.  
  1782.    p = gcvt(   g.objects[ g.objectnum ].mass , DBL_DIG ,
  1783.                &numberbuff[ 2 ][ 0 ] )  ;
  1784.    p = gcvt(   g.objects[ g.objectnum ].radius , DBL_DIG ,
  1785.                &numberbuff[ 3 ][ 0 ] )  ;
  1786.  
  1787.    p = gcvt(   g.objects[ g.objectnum ].startpos.x , DBL_DIG ,
  1788.                &numberbuff[ 4 ][ 0 ] )  ;
  1789.    p = gcvt(   g.objects[ g.objectnum ].startpos.y , DBL_DIG ,
  1790.                &numberbuff[ 6 ][ 0 ] )  ;
  1791.    p = gcvt(   g.objects[ g.objectnum ].startpos.z , DBL_DIG ,
  1792.                &numberbuff[ 8 ][ 0 ] )  ;
  1793.  
  1794.    p = gcvt(   g.objects[ g.objectnum ].startvel.x , DBL_DIG ,
  1795.                &numberbuff[ 5 ][ 0 ] )  ;
  1796.    p = gcvt(   g.objects[ g.objectnum ].startvel.y , DBL_DIG ,
  1797.                &numberbuff[ 7 ][ 0 ] )  ;
  1798.    p = gcvt(   g.objects[ g.objectnum ].startvel.z , DBL_DIG ,
  1799.                &numberbuff[ 9 ][ 0 ] )  ;
  1800.  
  1801.    RefreshGadgets( &controlgadg[ 31 ] , control , NULL )  ;
  1802.  }
  1803.  
  1804.  
  1805.  void deleteobject( num )
  1806.    long num  ;
  1807.  {
  1808.    Move( control->RPort , 48 , 21 + ( num * 14 ) )  ;
  1809.    Text( control->RPort , " " , 1 )  ;
  1810.    g.objects[ num ].flags = 0  ;
  1811.    g.objects[ num ].collision = 0  ;
  1812.    g.objects[ num ].position = zerodv  ;
  1813.    g.objects[ num ].startpos = zerodv  ;
  1814.    g.objects[ num ].velocity = zerodv  ;
  1815.    g.objects[ num ].startvel = zerodv  ;
  1816.    g.objects[ num ].oldpos = zerodv  ;
  1817.    g.objects[ num ].mass = 0.0  ;
  1818.    g.objects[ num ].startmass = 0.0  ;
  1819.    g.objects[ num ].radius = 0.0  ;
  1820.    g.objects[ num ].name[ 0 ] = 0  ;
  1821.  }
  1822.  
  1823.  
  1824.  void endtrail( i , j )
  1825.    long  i , j  ;
  1826.  {
  1827.    struct dv   op , tv ;
  1828.  
  1829.    if ( g.trailson )
  1830.    {
  1831.       if ( mainview )
  1832.          SetAPen( mainview->RPort , LINEPEN )  ;
  1833.       if ( topview )
  1834.          SetAPen( topview->RPort , LINEPEN )  ;
  1835.       if ( rightview )
  1836.          SetAPen( rightview->RPort , LINEPEN )  ;
  1837.    }
  1838.    else
  1839.    {
  1840.       if ( mainview )
  1841.          SetAPen( mainview->RPort , 0 )  ;
  1842.       if ( topview )
  1843.          SetAPen( topview->RPort , 0 )  ;
  1844.       if ( rightview )
  1845.          SetAPen( rightview->RPort , 0 )  ;
  1846.    }
  1847.    if ( g.follow )
  1848.    {
  1849.       subdv(   &g.objects[ i ].oldpos ,
  1850.                &g.objects[ g.objectnum ].oldpos , &tv )  ;
  1851.       basis( &tv , &g.viewbasis , &op )  ;
  1852.    }
  1853.    else
  1854.    {
  1855.       basis( &g.objects[ i ].oldpos , &g.viewbasis , &tv )  ;
  1856.       adddv( &tv , &g.viewoffset , &op )  ;
  1857.    }
  1858.    if ( mainview )
  1859.       pixel( mainview , op.x , op.y )  ;
  1860.    if ( topview )
  1861.       pixel( topview , op.x , -op.z )  ;
  1862.    if ( rightview )
  1863.       pixel( rightview , -op.z , op.y )  ;
  1864.    if ( g.follow )
  1865.    {
  1866.       subdv(   &g.objects[ j ].oldpos ,
  1867.                &g.objects[ g.objectnum ].oldpos , &tv )  ;
  1868.       basis( &tv , &g.viewbasis , &op )  ;
  1869.    }
  1870.    else
  1871.    {
  1872.       basis( &g.objects[ j ].oldpos , &g.viewbasis , &tv )  ;
  1873.       adddv( &tv , &g.viewoffset , &op )  ;
  1874.    }
  1875.    if ( mainview )
  1876.       pixel( mainview , op.x , op.y )  ;
  1877.    if ( topview )
  1878.       pixel( topview , op.x , -op.z )  ;
  1879.    if ( rightview )
  1880.       pixel( rightview , -op.z , op.y )  ;
  1881.  }
  1882.  
  1883.  
  1884.  void updatedisplay()
  1885.  {
  1886.    struct dv   np[ 20 ] , op[ 20 ] , tv ;
  1887.    long  i  ;
  1888.    char  *p  ;
  1889.  
  1890.    if ( g.trailson )
  1891.    {
  1892.       if ( mainview )
  1893.          SetAPen( mainview->RPort , LINEPEN )  ;
  1894.       if ( topview )
  1895.          SetAPen( topview->RPort , LINEPEN )  ;
  1896.       if ( rightview )
  1897.          SetAPen( rightview->RPort , LINEPEN )  ;
  1898.    }
  1899.    else
  1900.    {
  1901.       if ( mainview )
  1902.          SetAPen( mainview->RPort , 0 )  ;
  1903.       if ( topview )
  1904.          SetAPen( topview->RPort , 0 )  ;
  1905.       if ( rightview )
  1906.          SetAPen( rightview->RPort , 0 )  ;
  1907.    }
  1908.    for ( i = 0 ; i < 20 ; i ++ )
  1909.    {
  1910.       if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) )
  1911.       {
  1912.  
  1913.          if ( g.follow )
  1914.          {
  1915.             subdv(   &g.objects[ i ].position ,
  1916.                      &g.objects[ g.objectnum ].position , &tv )  ;
  1917.             basis( &tv , &g.viewbasis , &np[ i ] )  ;
  1918.             subdv(   &g.objects[ i ].oldpos ,
  1919.                      &g.objects[ g.objectnum ].oldpos , &tv )  ;
  1920.             basis( &tv , &g.viewbasis , &op[ i ] )  ;
  1921.          }
  1922.          else
  1923.          {
  1924.             basis( &g.objects[ i ].position , &g.viewbasis , &tv )  ;
  1925.             adddv( &tv , &g.viewoffset , &np[ i ] )  ;
  1926.             basis( &g.objects[ i ].oldpos , &g.viewbasis , &tv )  ;
  1927.             adddv( &tv , &g.viewoffset , &op[ i ] )  ;
  1928.          }
  1929.          if ( mainview )
  1930.             pixel( mainview , op[ i ].x , op[ i ].y )  ;
  1931.          if ( topview )
  1932.             pixel( topview , op[ i ].x , -op[ i ].z )  ;
  1933.          if ( rightview )
  1934.             pixel( rightview , -op[ i ].z , op[ i ].y )  ;
  1935.       }
  1936.    }
  1937.    if ( g.trailson )
  1938.    {
  1939.       if ( mainview )
  1940.          SetAPen( mainview->RPort , LINEPEN )  ;
  1941.       if ( topview )
  1942.          SetAPen( topview->RPort , LINEPEN )  ;
  1943.       if ( rightview )
  1944.          SetAPen( rightview->RPort , LINEPEN )  ;
  1945.       for ( i = 0 ; i < 20 ; i ++ )
  1946.       {
  1947.          if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) )
  1948.          {
  1949.             if ( mainview )
  1950.                line( mainview ,  op[ i ].x , op[ i ].y ,
  1951.                                  np[ i ].x , np[ i ].y )  ;
  1952.             if ( topview )
  1953.                line( topview ,   op[ i ].x , -op[ i ].z ,
  1954.                                  np[ i ].x , -np[ i ].z )  ;
  1955.             if ( rightview )
  1956.                line( rightview , -op[ i ].z , op[ i ].y ,
  1957.                                  -np[ i ].z , np[ i ].y )  ;
  1958.          }
  1959.       }
  1960.    }
  1961.    if ( mainview )
  1962.       SetAPen( mainview->RPort , DOTPEN )  ;
  1963.    if ( topview )
  1964.       SetAPen( topview->RPort , DOTPEN )  ;
  1965.    if ( rightview )
  1966.       SetAPen( rightview->RPort , DOTPEN )  ;
  1967.    for ( i = 0 ; i < 20 ; i ++ )
  1968.    {
  1969.       if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) )
  1970.       {
  1971.          if ( mainview )
  1972.             pixel( mainview , np[ i ].x , np[ i ].y )  ;
  1973.          if ( topview )
  1974.             pixel( topview , np[ i ].x , -np[ i ].z )  ;
  1975.          if ( rightview )
  1976.             pixel( rightview , -np[ i ].z , np[ i ].y )  ;
  1977.       }
  1978.    }
  1979.    p = gcvt( g.elapsedtime , DBL_DIG , &ettext[ 0 ] )  ;
  1980.    Move( control->RPort , 234 , 211 )  ;
  1981.    Text( control->RPort , &ettext[ 0 ] , strlen( &ettext[ 0 ] ) )  ;
  1982.    Text( control->RPort , "                " , 16 )  ;
  1983.  }
  1984.  
  1985.  
  1986.