/* GW-Interface.c Graphics and user control for Geavity-Well Gary Teachout Copyright July 1989 lc -x -cs GW-Interface To compile with Lattice 5.0 */ #include "GW-Include.h" void startup() { int i ; char *p ; IntuitionBase = ( struct IntuitionBase * ) OpenLibrary( "intuition.library" , 33 ) ; if ( ! IntuitionBase ) cleanup() ; GfxBase = ( struct GfxBase * ) OpenLibrary( "graphics.library" , 33 ) ; if ( ! GfxBase ) cleanup() ; DiskfontBase = ( struct Library * ) OpenLibrary( "diskfont.library" , 33 ) ; if ( ! DiskfontBase ) cleanup() ; rfont = OpenDiskFont( &rtext ) ; if ( ! rfont ) cleanup() ; ns.Font = &stext ; screen = OpenScreen( &ns ) ; if ( ! screen ) cleanup() ; for ( i = 0 ; i < 4 ; i ++ ) SetRGB4( &screen->ViewPort , i , clut[ i ][ 0 ] , clut[ i ][ 1 ] , clut[ i ][ 2 ] ) ; controlnw.Screen = screen ; viewcontrolnw.Screen = screen ; mainviewnw.Screen = screen ; topviewnw.Screen = screen ; rightviewnw.Screen = screen ; for ( i = 0 ; i < 12 ; i ++ ) { viewcongadg[ i ].GadgetID = i ; viewcongadg[ i ].NextGadget = ( i < 11 ) ? &viewcongadg[ i + 1 ] : NULL ; } viewcontrolnw.FirstGadget = &viewcongadg[ 0 ] ; for ( i = 0 ; i < 45 ; i ++ ) { controlgadg[ i ].GadgetID = i ; controlgadg[ i ].NextGadget = ( i < 44 ) ? &controlgadg[ i + 1 ] : NULL ; } controlnw.FirstGadget = &controlgadg[ 0 ] ; for ( i = 0 ; i < 14 ; i ++ ) { controlgadg[ 31 + i ].SpecialInfo = ( APTR ) &controlinfo[ i ] ; controlinfo[ i ].UndoBuffer = undobuffer ; } for ( i = 0 ; i < 4 ; i ++ ) { controlinfo[ i ].MaxChars = 66 ; controlgadg[ 31 + i ].GadgetRender = ( APTR ) &textbox ; } for ( i = 4 ; i < 14 ; i ++ ) { controlinfo[ i ].MaxChars = 33 ; controlinfo[ i ].Buffer = &numberbuff[ i - 4 ][ 0 ] ; controlgadg[ 31 + i ].GadgetRender = ( APTR ) &numberbox ; } controlinfo[ 0 ].MaxChars = 100 ; controlinfo[ 0 ].Buffer = filename ; controlinfo[ 1 ].Buffer = g.filecomment1 ; controlinfo[ 2 ].Buffer = g.filecomment2 ; controlinfo[ 3 ].Buffer = &g.objects[ g.objectnum ].name[ 0 ] ; textbox.XY = &xytextbox[ 0 ] ; numberbox.XY = &xynumbox[ 0 ] ; control = OpenWindow( &controlnw ) ; if ( ! control ) cleanup() ; SetFont( control->RPort , rfont ) ; openmainview() ; if ( ! mainview ) cleanup() ; SetAPen( control->RPort , BPEN ) ; Move( control->RPort , 90 , 10 ) ; Draw( control->RPort , 90 , 217 ) ; Draw( control->RPort , 638 , 217 ) ; SetBPen( control->RPort , LINEPEN ) ; SetAPen( control->RPort , DOTPEN ) ; for ( i = 0 ; i < 20 ; i ++ ) { Move( control->RPort , 10 , 21 + ( i * 14 ) ) ; Text( control->RPort , &numbertext[ i * 3 ] , 4 ) ; } for ( i = 0 ; i < 11 ; i ++ ) { Move( control->RPort , controlgadg[ 20 + i ].LeftEdge + 4 , controlgadg[ 20 + i ].TopEdge + 9 ) ; Text( control->RPort , controlgtext[ i ] , 8 ) ; } SetBPen( control->RPort , 0 ) ; SetAPen( control->RPort , DOTPEN ) ; Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) ) ; Text( control->RPort , "<-" , 2 ) ; Move( control->RPort , 48 , 21 + ( 0 * 14 ) ) ; Text( control->RPort , "*" , 1 ) ; Move( control->RPort , 48 , 21 + ( 1 * 14 ) ) ; Text( control->RPort , "*" , 1 ) ; Move( control->RPort , 48 , 21 + ( 2 * 14 ) ) ; Text( control->RPort , "*" , 1 ) ; for ( i = 0 ; i < 10 ; i ++ ) { Move( control->RPort , controlgadg[ 31 + i ].LeftEdge + 5 , controlgadg[ 31 + i ].TopEdge - 7 ) ; Text( control->RPort , conlabel[ i ] , conlabellength[ i ] ) ; } Move( control->RPort , 150 , 23 ) ; Text( control->RPort , "Gravity Well Celestial Motion Simulator" , 41 ) ; Move( control->RPort , 150 , 38 ) ; Text( control->RPort , "by Gary Teachout Freeware Copyright 1989" , 45 ) ; Move( control->RPort , 130 , 197 ) ; Text( control->RPort , "Scale:" , 6 ) ; p = gcvt( g.scale , DBL_DIG , &ettext[ 0 ] ) ; Move( control->RPort , 234 , 197 ) ; Text( control->RPort , &ettext[ 0 ] , strlen( &ettext[ 0 ] ) ) ; Move( control->RPort , 130 , 211 ) ; Text( control->RPort , "Elaped Time:" , 12 ) ; Move( control->RPort , 88 , 346 ) ; Text( control->RPort , "X" , 1 ) ; Move( control->RPort , 88 , 360 ) ; Text( control->RPort , "Y" , 1 ) ; Move( control->RPort , 88 , 374 ) ; Text( control->RPort , "Z" , 1 ) ; menustrip[ 0 ].FirstItem = &menu0[ 0 ].item ; menu0[ 0 ].item.ItemFill = ( APTR ) &menu0[ 0 ].text ; menu0[ 0 ].text.ITextFont = &rtext ; menustrip[ 1 ].FirstItem = &menu1[ 0 ].item ; for ( i = 0 ; i < 5 ; i ++ ) { menu1[ i ].item.ItemFill = ( APTR ) &menu1[ i ].text ; menu1[ i ].text.ITextFont = &rtext ; menu1[ i ].item.NextItem = ( i < 4 ) ? &menu1[ i + 1 ].item : NULL ; } menustrip[ 2 ].FirstItem = &menu2[ 0 ].item ; for ( i = 0 ; i < 4 ; i ++ ) { menu2[ i ].item.ItemFill = ( APTR ) &menu2[ i ].text ; menu2[ i ].text.ITextFont = &rtext ; menu2[ i ].item.NextItem = ( i < 3 ) ? &menu2[ i + 1 ].item : NULL ; } menustrip[ 0 ].NextMenu = &menustrip[ 1 ] ; menustrip[ 1 ].NextMenu = &menustrip[ 2 ] ; SetMenuStrip( control , &menustrip[ 0 ] ) ; openviewcontrol() ; opentopview() ; openrightview() ; openviewcontrol() ; set() ; } void cleanup() { if ( control ) { ClearMenuStrip( control ) ; CloseWindow( control ) ; } if ( viewcontrol ) { ClearMenuStrip( viewcontrol ) ; CloseWindow( viewcontrol ) ; } if ( mainview ) { ClearMenuStrip( mainview ) ; CloseWindow( mainview ) ; } if ( topview ) { ClearMenuStrip( topview ) ; CloseWindow( topview ) ; } if ( rightview ) { ClearMenuStrip( rightview ) ; CloseWindow( rightview ) ; } if ( screen ) CloseScreen( screen ) ; if ( rfont ) CloseFont( rfont ) ; if ( DiskfontBase ) CloseLibrary( DiskfontBase ) ; if ( GfxBase ) CloseLibrary( GfxBase ) ; if ( IntuitionBase ) CloseLibrary( IntuitionBase ) ; exit() ; } void openmainview() { if ( mainview ) { WindowToFront( mainview ) ; } else { mainview = OpenWindow( &mainviewnw ) ; if ( mainview ) { SetMenuStrip( mainview , &menustrip[ 0 ] ) ; setupdisplay( mainview ) ; } else { DisplayBeep( screen ) ; } } } void opentopview() { if ( topview ) { WindowToFront( topview ) ; } else { topview = OpenWindow( &topviewnw ) ; if ( topview ) { SetMenuStrip( topview , &menustrip[ 0 ] ) ; setupdisplay( topview ) ; } else { DisplayBeep( screen ) ; } } } void openrightview() { if ( rightview ) { WindowToFront( rightview ) ; } else { rightview = OpenWindow( &rightviewnw ) ; if ( rightview ) { SetMenuStrip( rightview , &menustrip[ 0 ] ) ; setupdisplay( rightview ) ; } else { DisplayBeep( screen ) ; } } } void openviewcontrol() { long i ; if ( viewcontrol ) { WindowToFront( viewcontrol ) ; } else { viewcontrol = OpenWindow( &viewcontrolnw ) ; if ( viewcontrol ) { SetFont( viewcontrol->RPort , rfont ) ; SetMenuStrip( viewcontrol , &menustrip[ 0 ] ) ; SetBPen( viewcontrol->RPort , LINEPEN ) ; SetAPen( viewcontrol->RPort , DOTPEN ) ; for ( i = 0 ; i < 3 ; i ++ ) { Move( viewcontrol->RPort , 14 , 86 + ( i * 16 ) ) ; Text( viewcontrol->RPort , "<" , 1 ) ; Move( viewcontrol->RPort , 78 , 86 + ( i * 16 ) ) ; Text( viewcontrol->RPort , ">" , 1 ) ; } Move( viewcontrol->RPort , 18 , 22 + ( 0 * 16 ) ) ; Text( viewcontrol->RPort , " Follow " , 8 ) ; Move( viewcontrol->RPort , 18 , 22 + ( 1 * 16 ) ) ; Text( viewcontrol->RPort , " Center " , 8 ) ; Move( viewcontrol->RPort , 18 , 22 + ( 2 * 16 ) ) ; Text( viewcontrol->RPort , " Trails " , 8 ) ; Move( viewcontrol->RPort , 22 , 22 + ( 7 * 16 ) ) ; Text( viewcontrol->RPort , " Reset " , 7 ) ; Move( viewcontrol->RPort , 14 , 22 + ( 9 * 16 ) ) ; Text( viewcontrol->RPort , "IN" , 2 ) ; Move( viewcontrol->RPort , 62 , 22 + ( 9 * 16 ) ) ; Text( viewcontrol->RPort , "OUT" , 3 ) ; SetBPen( viewcontrol->RPort , 0 ) ; Move( viewcontrol->RPort , 18 , 22 + ( 3 * 16 ) ) ; Text( viewcontrol->RPort , "-Rotate-" , 8 ) ; Move( viewcontrol->RPort , 34 , 22 + ( 4 * 16 ) ) ; Text( viewcontrol->RPort , "Main" , 4 ) ; Move( viewcontrol->RPort , 38 , 22 + ( 5 * 16 ) ) ; Text( viewcontrol->RPort , "Top" , 3 ) ; Move( viewcontrol->RPort , 30 , 22 + ( 6 * 16 ) ) ; Text( viewcontrol->RPort , "Right" , 5 ) ; Move( viewcontrol->RPort , 26 , 22 + ( 8 * 16 ) ) ; Text( viewcontrol->RPort , "-Zoom-" , 6 ) ; } else DisplayBeep( screen ) ; } } void pixel( w , x , y ) struct Window *w ; double x , y ; { long xx , yy ; xx = ( w->Width >> 1 ) + ( long ) ( g.scale * x * 200.0 ) ; yy = ( w->Height >> 1 ) - ( long ) ( g.scale * y * 177.0 ) ; if ( ( xx > w->BorderLeft ) && ( xx < ( w->Width - w->BorderRight ) ) && ( yy > w->BorderTop ) && ( yy < ( w->Height - w->BorderBottom ) ) ) { WritePixel( w->RPort , xx , yy ) ; WritePixel( w->RPort , xx + 1 , yy ) ; } } void blankwindow( w ) struct Window *w ; { if ( w ) { SetAPen( w->RPort , 0 ) ; RectFill( w->RPort , w->BorderLeft - 1 , w->BorderTop - 1 , w->Width - w->BorderRight , w->Height - w->BorderBottom ) ; } } void line( w , x1 , y1 , x2 , y2 ) struct Window *w ; double x1 , y1 , x2 , y2 ; { long xx1 , yy1 , xx2 , yy2 ; xx1 = ( w->Width >> 1 ) + ( long ) ( g.scale * x1 * 200.0 ) ; yy1 = ( w->Height >> 1 ) - ( long ) ( g.scale * y1 * 177.0 ) ; xx2 = ( w->Width >> 1 ) + ( long ) ( g.scale * x2 * 200.0 ) ; yy2 = ( w->Height >> 1 ) - ( long ) ( g.scale * y2 * 177.0 ) ; if ( ( xx1 > w->BorderLeft ) && ( xx1 < ( w->Width - w->BorderRight ) ) && ( yy1 > w->BorderTop ) && ( yy1 < ( w->Height - w->BorderBottom ) ) && ( xx2 > w->BorderLeft ) && ( xx2 < ( w->Width - w->BorderRight ) ) && ( yy2 > w->BorderTop ) && ( yy2 < ( w->Height - w->BorderBottom ) ) ) { Move( w->RPort , xx1 , yy1 ) ; Draw( w->RPort , xx2 , yy2 ) ; } } void linelong( w , x1 , y1 , x2 , y2 ) struct Window *w ; long x1 , y1 , x2 , y2 ; { if ( x1 < w->BorderLeft ) { if ( x2 < w->BorderLeft ) return ; y1 = y1 + ( double ) ( y2 - y1 ) / ( x2 - x1 ) * ( w->BorderLeft - x1 ) ; x1 = w->BorderLeft ; } else if ( x1 > ( w->Width - w->BorderRight ) ) { if ( x2 > ( w->Width - w->BorderRight ) ) return ; y1 = y1 + ( double ) ( y2 - y1 ) / ( x2 - x1 ) * ( w->Width - w->BorderRight - x1 ) ; x1 = w->Width - w->BorderRight ; } if ( y1 < w->BorderTop ) { if ( y2 < w->BorderTop ) return ; x1 = x1 + ( double ) ( x2 - x1 ) / ( y2 - y1 ) * ( w->BorderTop - y1 ) ; y1 = w->BorderTop ; if ( ( x1 < w->BorderLeft ) || ( x1 > ( w->Width - w->BorderRight ) ) ) return ; } else if ( y1 > ( w->Height - w->BorderBottom ) ) { if ( y2 > ( w->Height - w->BorderBottom ) ) return ; x1 = x1 + ( double ) ( x2 - x1 ) / ( y2 - y1 ) * ( w->Height - w->BorderBottom - y1 ) ; y1 = w->Height - w->BorderBottom ; if ( ( x1 < w->BorderLeft ) || ( x1 > ( w->Width - w->BorderRight ) ) ) return ; } if ( x2 < w->BorderLeft ) { y2 = y2 + ( double ) ( y1 - y2 ) / ( x1 - x2 ) * ( w->BorderLeft - x2 ) ; x2 = w->BorderLeft ; } else if ( x2 > ( w->Width - w->BorderRight ) ) { y2 = y2 + ( double ) ( y1 - y2 ) / ( x1 - x2 ) * ( w->Width - w->BorderRight - x2 ) ; x2 = w->Width - w->BorderRight ; } if ( y2 < w->BorderTop ) { x2 = x2 + ( double ) ( x1 - x2 ) / ( y1 - y2 ) * ( w->BorderTop - y2 ) ; y2 = w->BorderTop ; } else if ( y2 > ( w->Height - w->BorderBottom ) ) { x2 = x2 + ( double ) ( x1 - x2 ) / ( y1 - y2 ) * ( w->Height - w->BorderBottom - y2 ) ; y2 = w->Height - w->BorderBottom ; } Move( w->RPort , x1 , y1 ) ; Draw( w->RPort , x2 , y2 ) ; } void interface() { struct FileHandle *fh ; struct filedata *fd ; long i , s ; struct dv tv , vv ; double x , y ; char *p ; if ( control ) { while ( mes = GetMsg( control->UserPort ) ) { readmes() ; switch ( class ) { case MENUPICK : handelmenu() ; break ; case GADGETUP : if ( ( iadd->GadgetID < 20 ) && ( g.objects[ iadd->GadgetID ].flags || ( g.awaiting == NEWPOSITION ) || ( g.awaiting == NEWMASS ) || ( g.awaiting == NEWCREATE ) || ( g.awaiting == NEWVELOCITY ) ) ) { Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) ) ; Text( control->RPort , " " , 2 ) ; g.objectnum = iadd->GadgetID ; Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) ) ; Text( control->RPort , "<-" , 2 ) ; setstrings() ; if ( g.follow ) resetdisplay() ; } else { switch ( iadd->GadgetID ) { case 20 : g.awaiting = NEWPOSITION ; screentitle( NEWPOSITION ) ; break ; case 21 : g.awaiting = NEWVELOCITY ; screentitle( NEWVELOCITY ) ; break ; case 22 : g.awaiting = NEWMASS ; screentitle( NEWMASS ) ; break ; case 23 : /* delete */ deleteobject( g.objectnum ) ; resetdisplay() ; break ; case 24 : /* zero M */ for ( tv = zerodv , x = 0.0 , i = 0 ; i < 20 ; i ++ ) { if ( g.objects[ i ].flags && g.objects[ i ].mass ) { scaledv( &g.objects[ i ].velocity , &g.objects[ i ].mass , &vv ) ; adddv( &tv , &vv , &tv ) ; x = x + g.objects[ i ].mass ; } } if ( x ) { x = 1 / x ; scaledv( &tv , &x , &tv ) ; for ( i = 0 ; i < 20 ; i ++ ) { if ( g.objects[ i ].flags ) { subdv( &g.objects[ i ].velocity , &tv , &g.objects[ i ].velocity ) ; } } } set() ; break ; case 25 : if ( g.awaiting > 1 ) { g.awaiting = 0 ; resetdisplay() ; } g.awaiting = 0 ; screentitle( 0 ) ; g.stopflag = 0 ; break ; case 26 : /* load */ Move( control->RPort , 200 , 62 ) ; p = AllocMem( 4700 , MEMF_CHIP |MEMF_CLEAR ) ; s = 1 ; if ( p ) { fh = Open( filename , MODE_OLDFILE ) ; if ( fh ) { ScreenToFront( screen ) ; Text( control->RPort , "Loading file " , 29 ) ; fd = ( struct filedata * ) p ; i = Read( fh , p , 4700 ) ; if ( i == 4700 ) { for ( i = 0 ; i < 12 ; i ++ ) if ( fd->tag[ i ] != g.tag[ i ] ) i = 20 ; if ( i < 20 ) { s = g.stopflag ; g = *fd ; for ( i = 0 ; i < 20 ; i ++ ) { Move( control->RPort , 48 , 21 + ( i * 14 ) ) ; if ( g.objects[ i ].flags ) Text( control->RPort , "* " , 4 ) ; else Text( control->RPort , " " , 4 ) ; } Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) ) ; Text( control->RPort , "<-" , 2 ) ; screentitle( g.awaiting ) ; setstrings() ; resetdisplay() ; Delay( 100 ) ; Move( control->RPort , 200 , 62 ) ; Text( control->RPort , " " , 29 ) ; } else { Move( control->RPort , 200 , 62 ) ; Text( control->RPort , "ERROR Not a Gravity Well file" , 29 ) ; } } else { Move( control->RPort , 200 , 62 ) ; Text( control->RPort , "ERROR While reading file " , 29 ) ; } Close( fh ) ; } else Text( control->RPort , "ERROR Could not open file " , 29 ) ; ScreenToFront( screen ) ; FreeMem( p , 4700 ) ; } else Text( control->RPort , "ERROR Out of memory " , 29 ) ; if ( g.stopflag && ( ! s ) ) stoploop() ; break ; case 27 : /* save */ Move( control->RPort , 200 , 62 ) ; p = AllocMem( 4700 , MEMF_CHIP |MEMF_CLEAR ) ; if ( p ) { fh = Open( filename , MODE_NEWFILE ) ; if ( fh ) { ScreenToFront( screen ) ; Text( control->RPort , "Saving file " , 29 ) ; Move( control->RPort , 200 , 62 ) ; fd = ( struct filedata * ) p ; *fd = g ; i = Write( fh , p , 4700 ) ; if ( i == 4700 ) { Delay( 100 ) ; Text( control->RPort , " " , 29 ) ; } else Text( control->RPort , "ERROR While writing file " , 29 ) ; Close( fh ) ; } else Text( control->RPort , "ERROR Could not open file " , 29 ) ; ScreenToFront( screen ) ; FreeMem( p , 4700 ) ; } else Text( control->RPort , "ERROR Out of memory " , 29 ) ; break ; case 28 : for ( i = 0 ; i < 20 ; i ++ ) deleteobject( i ) ; g.elapsedtime = 0.0 ; g.timestep = 0.01 ; g.magic = 100.0 ; g.scale = 0.5 ; g.trailson = 1 ; g.follow = 0 ; g.viewbasis = refobv ; g.viewoffset = zerodv ; g.filecomment1[ 0 ] = 0 ; g.filecomment2[ 0 ] = 0 ; setstrings() ; resetdisplay() ; if ( ! g.stopflag ) { g.stopflag = 1 ; stoploop() ; } break ; case 29 : g.awaiting = NEWCREATE ; screentitle( NEWCREATE ) ; break ; case 30 : create() ; g.timestep = atof( &numberbuff[ 0 ][ 0 ] ) ; g.magic = atof( &numberbuff[ 1 ][ 0 ] ) ; g.objects[ g.objectnum ].mass = atof( &numberbuff[ 2 ][ 0 ] ) ; g.objects[ g.objectnum ].radius = atof( &numberbuff[ 3 ][ 0 ] ) ; g.objects[ g.objectnum ].position.x = atof( &numberbuff[ 4 ][ 0 ] ) ; g.objects[ g.objectnum ].position.y = atof( &numberbuff[ 6 ][ 0 ] ) ; g.objects[ g.objectnum ].position.z = atof( &numberbuff[ 8 ][ 0 ] ) ; g.objects[ g.objectnum ].velocity.x = atof( &numberbuff[ 5 ][ 0 ] ) ; g.objects[ g.objectnum ].velocity.y = atof( &numberbuff[ 7 ][ 0 ] ) ; g.objects[ g.objectnum ].velocity.z = atof( &numberbuff[ 9 ][ 0 ] ) ; set() ; setstrings() ; resetdisplay() ; break ; case 35 : g.timestep = atof( &numberbuff[ 0 ][ 0 ] ) ; p = gcvt( g.timestep , DBL_DIG , &numberbuff[ 0 ][ 0 ] ) ; RefreshGadgets( &controlgadg[ 31 ] , control , NULL ) ; break ; case 36 : g.magic = atof( &numberbuff[ 1 ][ 0 ] ) ; p = gcvt( g.magic , DBL_DIG , &numberbuff[ 1 ][ 0 ] ) ; RefreshGadgets( &controlgadg[ 31 ] , control , NULL ) ; break ; } } if ( g.awaiting > 1 ) { g.follow = 0 ; resetdisplay() ; if ( ! g.stopflag ) { g.stopflag = 1 ; stoploop() ; } } break ; } } } if ( viewcontrol ) { while ( mes = GetMsg( viewcontrol->UserPort ) ) { readmes() ; switch ( class ) { case MENUPICK : handelmenu() ; break ; case CLOSEWINDOW : ClearMenuStrip( viewcontrol ) ; viewcontrolnw.LeftEdge = viewcontrol->LeftEdge ; viewcontrolnw.TopEdge = viewcontrol->TopEdge ; CloseWindow( viewcontrol ) ; viewcontrol = NULL ; break ; case GADGETUP : switch ( iadd->GadgetID ) { case 0 : rotatedvpair10( &g.viewbasis.j , &g.viewbasis.i ) ; break ; case 1 : rotatedvpair10( &g.viewbasis.i , &g.viewbasis.j ) ; break ; case 2 : rotatedvpair10( &g.viewbasis.i , &g.viewbasis.k ) ; break ; case 3 : rotatedvpair10( &g.viewbasis.k , &g.viewbasis.i ) ; break ; case 4 : rotatedvpair10( &g.viewbasis.k , &g.viewbasis.j ) ; break ; case 5 : rotatedvpair10( &g.viewbasis.j , &g.viewbasis.k ) ; break ; case 6 : g.viewbasis = refobv ; g.unviewbasis = refobv ; break ; case 7 : g.scale = g.scale * 1.6 ; p = gcvt( g.scale , DBL_DIG , &ettext[ 0 ] ) ; Move( control->RPort , 234 , 197 ) ; Text( control->RPort , &ettext[ 0 ] , strlen( &ettext[ 0 ] ) ) ; Text( control->RPort , " " , 20 ) ; break ; case 8 : g.scale = g.scale * 0.625 ; p = gcvt( g.scale , DBL_DIG , &ettext[ 0 ] ) ; Move( control->RPort , 234 , 197 ) ; Text( control->RPort , &ettext[ 0 ] , strlen( &ettext[ 0 ] ) ) ; Text( control->RPort , " " , 20 ) ; break ; case 9 : if ( g.trailson ) { g.trailson = 0 ; resetdisplay() ; } else g.trailson = 1 ; break ; case 10 : if ( g.awaiting == NEWCENTER ) { screentitle( 0 ) ; g.awaiting = 0 ; } else { if ( g.follow ) { g.follow = 0 ; resetdisplay() ; } else if ( g.awaiting ) resetdisplay() ; screentitle( NEWCENTER ) ; g.awaiting = NEWCENTER ; } break ; case 11 : g.follow = ( g.follow ) ? 0 : 1 ; break ; } if ( iadd->GadgetID != 10 ) { if ( g.awaiting == NEWCENTER ) { screentitle( 0 ) ; g.awaiting = 0 ; } resetdisplay() ; } if ( iadd->GadgetID < 6 ) { basis( &refobv.i , &g.viewbasis , &g.unviewbasis.i ) ; basis( &refobv.j , &g.viewbasis , &g.unviewbasis.j ) ; basis( &refobv.k , &g.viewbasis , &g.unviewbasis.k ) ; } break ; } if ( ! viewcontrol ) break ; } } if ( mainview ) { while ( mes = GetMsg( mainview->UserPort ) ) { readmes() ; switch ( class ) { case MENUPICK : handelmenu() ; break ; case NEWSIZE : blankwindow( mainview ) ; setupdisplay( mainview ) ; break ; case CLOSEWINDOW : ClearMenuStrip( mainview ) ; mainviewnw.LeftEdge = mainview->LeftEdge ; mainviewnw.TopEdge = mainview->TopEdge ; mainviewnw.Width = mainview->Width ; mainviewnw.Height = mainview->Height ; CloseWindow( mainview ) ; mainview = NULL ; break ; case MOUSEBUTTONS : if ( code == SELECTDOWN ) { switch ( g.awaiting ) { case NEWCENTER : g.viewoffset.x = g.viewoffset.x - ( ( mousex - ( mainview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; g.viewoffset.y = g.viewoffset.y + ( ( mousey - ( mainview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; resetdisplay() ; break ; case NEWPOSITION : create() ; basis( &g.objects[ g.objectnum ].position , &g.viewbasis , &tv ) ; do { tv.x = -g.viewoffset.x + ( ( mainview->MouseX - ( mainview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; tv.y = -g.viewoffset.y - ( ( mainview->MouseY - ( mainview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; basis( &tv , &g.unviewbasis , &g.objects[ g.objectnum ].position ) ; resetdisplay() ; Delay( 1 ) ; if ( mes = GetMsg( mainview->UserPort ) ) readmes() ; } while ( ( class != MOUSEBUTTONS ) || ( code != SELECTUP ) ) ; g.objects[ g.objectnum ].oldpos = g.objects[ g.objectnum ].position ; set() ; break ; case NEWVELOCITY : create() ; adddv( &g.objects[ g.objectnum ].position , &g.objects[ g.objectnum ].velocity , &vv ) ; basis( &vv , &g.viewbasis , &tv ) ; do { tv.x = -g.viewoffset.x + ( ( mainview->MouseX - ( mainview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; tv.y = -g.viewoffset.y - ( ( mainview->MouseY - ( mainview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; basis( &tv , &g.unviewbasis , &vv ) ; subdv( &vv , &g.objects[ g.objectnum ].position , &g.objects[ g.objectnum ].velocity ) ; resetdisplay() ; Delay( 1 ) ; if ( mes = GetMsg( mainview->UserPort ) ) readmes() ; } while ( ( class != MOUSEBUTTONS ) || ( code != SELECTUP ) ) ; set() ; break ; case NEWMASS : create() ; basis( &g.objects[ g.objectnum ].position , &g.viewbasis , &tv ) ; do { x = -g.viewoffset.x + ( ( mainview->MouseX - ( mainview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; y = -g.viewoffset.y - ( ( mainview->MouseY - ( mainview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; x = x - tv.x ; y = y - tv.y ; g.objects[ g.objectnum ].mass = sqrt( x * x + y * y ) ; resetdisplay() ; Delay( 1 ) ; if ( mes = GetMsg( mainview->UserPort ) ) readmes() ; } while ( ( class != MOUSEBUTTONS ) || ( code != SELECTUP ) ) ; set() ; break ; } } break ; } if ( ! mainview ) break ; } } if ( topview ) { while ( mes = GetMsg( topview->UserPort ) ) { readmes() ; switch ( class ) { case MENUPICK : handelmenu() ; break ; case NEWSIZE : blankwindow( topview ) ; setupdisplay( topview ) ; break ; case CLOSEWINDOW : ClearMenuStrip( topview ) ; topviewnw.LeftEdge = topview->LeftEdge ; topviewnw.TopEdge = topview->TopEdge ; topviewnw.Width = topview->Width ; topviewnw.Height = topview->Height ; CloseWindow( topview ) ; topview = NULL ; break ; case MOUSEBUTTONS : if ( code == SELECTDOWN ) { switch ( g.awaiting ) { case NEWCENTER : g.viewoffset.x = g.viewoffset.x - ( ( mousex - ( topview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; g.viewoffset.z = g.viewoffset.z - ( ( mousey - ( topview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; resetdisplay() ; break ; case NEWPOSITION : create() ; basis( &g.objects[ g.objectnum ].position , &g.viewbasis , &tv ) ; do { tv.x = -g.viewoffset.x + ( ( topview->MouseX - ( topview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; tv.z = -g.viewoffset.z + ( ( topview->MouseY - ( topview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; basis( &tv , &g.unviewbasis , &g.objects[ g.objectnum ].position ) ; resetdisplay() ; Delay( 1 ) ; if ( mes = GetMsg( topview->UserPort ) ) readmes() ; } while ( ( class != MOUSEBUTTONS ) || ( code != SELECTUP ) ) ; g.objects[ g.objectnum ].oldpos = g.objects[ g.objectnum ].position ; set() ; break ; case NEWVELOCITY : create() ; adddv( &g.objects[ g.objectnum ].position , &g.objects[ g.objectnum ].velocity , &vv ) ; basis( &vv , &g.viewbasis , &tv ) ; do { tv.x = -g.viewoffset.x + ( ( topview->MouseX - ( topview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; tv.z = -g.viewoffset.z + ( ( topview->MouseY - ( topview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; basis( &tv , &g.unviewbasis , &vv ) ; subdv( &vv , &g.objects[ g.objectnum ].position , &g.objects[ g.objectnum ].velocity ) ; resetdisplay() ; Delay( 1 ) ; if ( mes = GetMsg( topview->UserPort ) ) readmes() ; } while ( ( class != MOUSEBUTTONS ) || ( code != SELECTUP ) ) ; set() ; break ; case NEWMASS : create() ; basis( &g.objects[ g.objectnum ].position , &g.viewbasis , &tv ) ; do { x = -g.viewoffset.x + ( ( topview->MouseX - ( topview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; y = -g.viewoffset.z + ( ( topview->MouseY - ( topview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; x = x - tv.x ; y = y - tv.z ; g.objects[ g.objectnum ].mass = sqrt( x * x + y * y ) ; resetdisplay() ; Delay( 1 ) ; if ( mes = GetMsg( topview->UserPort ) ) readmes() ; } while ( ( class != MOUSEBUTTONS ) || ( code != SELECTUP ) ) ; set() ; break ; } } break ; } if ( ! topview ) break ; } } if ( rightview ) { while ( mes = GetMsg( rightview->UserPort ) ) { readmes() ; switch ( class ) { case MENUPICK : handelmenu() ; break ; case NEWSIZE : blankwindow( rightview ) ; setupdisplay( rightview ) ; break ; case CLOSEWINDOW : ClearMenuStrip( rightview ) ; rightviewnw.LeftEdge = rightview->LeftEdge ; rightviewnw.TopEdge = rightview->TopEdge ; rightviewnw.Width = rightview->Width ; rightviewnw.Height = rightview->Height ; CloseWindow( rightview ) ; rightview = NULL ; break ; case MOUSEBUTTONS : if ( code == SELECTDOWN ) { switch ( g.awaiting ) { case NEWCENTER : g.viewoffset.z = g.viewoffset.z + ( ( mousex - ( rightview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; g.viewoffset.y = g.viewoffset.y + ( ( mousey - ( rightview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; resetdisplay() ; break ; case NEWPOSITION : create() ; basis( &g.objects[ g.objectnum ].position , &g.viewbasis , &tv ) ; do { tv.z = -g.viewoffset.z - ( ( rightview->MouseX - ( rightview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; tv.y = -g.viewoffset.y - ( ( rightview->MouseY - ( rightview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; basis( &tv , &g.unviewbasis , &g.objects[ g.objectnum ].position ) ; resetdisplay() ; Delay( 1 ) ; if ( mes = GetMsg( rightview->UserPort ) ) readmes() ; } while ( ( class != MOUSEBUTTONS ) || ( code != SELECTUP ) ) ; g.objects[ g.objectnum ].oldpos = g.objects[ g.objectnum ].position ; set() ; break ; case NEWVELOCITY : create() ; adddv( &g.objects[ g.objectnum ].position , &g.objects[ g.objectnum ].velocity , &vv ) ; basis( &vv , &g.viewbasis , &tv ) ; do { tv.z = -g.viewoffset.z - ( ( rightview->MouseX - ( rightview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; tv.y = -g.viewoffset.y - ( ( rightview->MouseY - ( rightview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; basis( &tv , &g.unviewbasis , &vv ) ; subdv( &vv , &g.objects[ g.objectnum ].position , &g.objects[ g.objectnum ].velocity ) ; resetdisplay() ; Delay( 1 ) ; if ( mes = GetMsg( rightview->UserPort ) ) readmes() ; } while ( ( class != MOUSEBUTTONS ) || ( code != SELECTUP ) ) ; set() ; break ; case NEWMASS : create() ; basis( &g.objects[ g.objectnum ].position , &g.viewbasis , &tv ) ; do { x = -g.viewoffset.z - ( ( rightview->MouseX - ( rightview->Width >> 1 ) ) / ( g.scale * 200.0 ) ) ; y = -g.viewoffset.y - ( ( rightview->MouseY - ( rightview->Height >> 1 ) ) / ( g.scale * 177.0 ) ) ; x = x - tv.z ; y = y - tv.y ; g.objects[ g.objectnum ].mass = sqrt( x * x + y * y ) ; resetdisplay() ; Delay( 1 ) ; if ( mes = GetMsg( rightview->UserPort ) ) readmes() ; } while ( ( class != MOUSEBUTTONS ) || ( code != SELECTUP ) ) ; set() ; break ; } } break ; } if ( ! rightview ) break ; } } if ( ( g.awaiting != NEWPOSITION ) && ( g.awaiting != NEWVELOCITY ) && ( g.awaiting != NEWMASS ) && ( g.awaiting != NEWCREATE ) && ( ! g.objects[ g.objectnum ].flags ) ) { for ( i = 0 ; ( ! g.objects[ i ].flags ) && ( i < 19 ) ; i ++ ) ; if ( ( i == 19 ) && ( ! g.objects[ 19 ].flags ) ) i = 0 ; Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) ) ; Text( control->RPort , " " , 2 ) ; g.objectnum = i ; Move( control->RPort , 58 , 21 + ( g.objectnum * 14 ) ) ; Text( control->RPort , "<-" , 2 ) ; setstrings() ; } } void readmes() { class = mes->Class ; code = mes->Code ; mousex = mes->MouseX ; mousey = mes->MouseY ; iadd = ( struct Gadget * ) mes->IAddress ; ReplyMsg( mes ) ; } void handelmenu() { long i ; switch ( MENUNUM( code ) ) { case 0 : if ( ITEMNUM( code ) == 0 ) cleanup() ; break ; case 1 : switch ( ITEMNUM( code ) ) { case 0 : openmainview() ; break ; case 1 : opentopview() ; break ; case 2 : openrightview() ; break ; case 3 : openviewcontrol() ; break ; case 4 : WindowToFront( control ) ; break ; } break ; case 2 : switch ( ITEMNUM( code ) ) { case 0 : if ( g.awaiting > 1 ) { g.awaiting = 0 ; resetdisplay() ; } g.awaiting = 0 ; screentitle( 0 ) ; g.stopflag = 0 ; break ; case 1 : if ( ! g.stopflag ) { g.stopflag = 1 ; stoploop() ; } break ; case 2 : set() ; break ; case 3 : g.elapsedtime = 0 ; for ( i = 0 ; i < 20 ; i ++ ) { g.objects[ i ].collision = 0 ; g.objects[ i ].mass = g.objects[ i ].startmass ; g.objects[ i ].position = g.objects[ i ].startpos ; g.objects[ i ].oldpos = g.objects[ i ].startpos ; g.objects[ i ].velocity = g.objects[ i ].startvel ; } resetdisplay() ; break ; } break ; } } void stoploop() { ULONG s ; while ( g.stopflag ) { s = 1 << control->UserPort->mp_SigBit ; if ( viewcontrol ) s |= 1 << viewcontrol->UserPort->mp_SigBit ; if ( mainview ) s |= 1 << mainview->UserPort->mp_SigBit ; if ( topview ) s |= 1 << topview->UserPort->mp_SigBit ; if ( rightview ) s |= 1 << rightview->UserPort->mp_SigBit ; Wait( s ) ; interface() ; } } void resetdisplay() { char *p ; blankwindow( mainview ) ; setupdisplay( mainview ) ; blankwindow( topview ) ; setupdisplay( topview ) ; blankwindow( rightview ) ; setupdisplay( rightview ) ; p = gcvt( g.elapsedtime , DBL_DIG , &ettext[ 0 ] ) ; Move( control->RPort , 234 , 211 ) ; Text( control->RPort , &ettext[ 0 ] , strlen( &ettext[ 0 ] ) ) ; Text( control->RPort , " " , 20 ) ; p = gcvt( g.scale , DBL_DIG , &ettext[ 0 ] ) ; Move( control->RPort , 234 , 197 ) ; Text( control->RPort , &ettext[ 0 ] , strlen( &ettext[ 0 ] ) ) ; Text( control->RPort , " " , 20 ) ; } void screentitle( n ) long n ; { SetWindowTitles( control , -1 , titletext[ n ] ) ; if ( viewcontrol ) SetWindowTitles( viewcontrol , -1 , titletext[ n ] ) ; if ( mainview ) SetWindowTitles( mainview , -1 , titletext[ n ] ) ; if ( topview ) SetWindowTitles( topview , -1 , titletext[ n ] ) ; if ( rightview ) SetWindowTitles( rightview , -1 , titletext[ n ] ) ; } void setupdisplay( w ) struct Window *w ; { struct dv np , vv ; long xx , yy , tx , ty , ux , uy , i ; if ( ! w ) return ; if ( g.awaiting > 1 ) { basis( &g.objects[ g.objectnum ].position , &g.viewbasis , &np ) ; adddv( &np , &g.viewoffset , &np ) ; if ( w == mainview ) { SetAPen( mainview->RPort , DOTPEN ) ; xx = ( mainview->Width >> 1 ) + ( long ) ( g.scale * np.x * 200.0 ) ; yy = ( mainview->Height >> 1 ) - ( long ) ( g.scale * np.y * 177.0 ) ; linelong( mainview , xx - 6 , yy , xx + 6 , yy ) ; linelong( mainview , xx , yy - 5 , xx , yy + 5 ) ; if ( g.awaiting == NEWVELOCITY ) { SetAPen( mainview->RPort , LINEPEN ) ; for( i = 0 ; i < 20 ; i ++ ) { if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) ) { basis( &g.objects[ i ].position , &g.viewbasis , &np ) ; adddv( &np , &g.viewoffset , &np ) ; xx = ( mainview->Width >> 1 ) + ( long ) ( g.scale * np.x * 200.0 ) ; yy = ( mainview->Height >> 1 ) - ( long ) ( g.scale * np.y * 177.0 ) ; adddv( &g.objects[ i ].position , &g.objects[ i ].velocity , &np ) ; basis( &np , &g.viewbasis , &vv ) ; adddv( &vv , &g.viewoffset , &vv ) ; tx = ( mainview->Width >> 1 ) + ( long ) ( g.scale * vv.x * 200.0 ) ; ty = ( mainview->Height >> 1 ) - ( long ) ( g.scale * vv.y * 177.0 ) ; linelong( mainview , xx , yy , tx , ty ) ; } } } else if ( g.awaiting == NEWMASS ) { SetAPen( mainview->RPort , LINEPEN ) ; for( i = 0 ; i < 20 ; i ++ ) { if ( ( g.objects[ i ].flags ) && ( g.objects[ i ].mass ) && ( ! g.objects[ i ].collision ) ) { basis( &g.objects[ i ].position , &g.viewbasis , &np ) ; adddv( &np , &g.viewoffset , &np ) ; xx = ( mainview->Width >> 1 ) + ( long ) ( g.scale * np.x * 200.0 ) ; yy = ( mainview->Height >> 1 ) - ( long ) ( g.scale * np.y * 177.0 ) ; tx = ( long ) ( g.scale * g.objects[ i ].mass * 200.0 ) ; ty = ( long ) ( g.scale * g.objects[ i ].mass * 177.0 ) ; ux = ( long ) ( g.scale * g.objects[ i ].mass * 80.0 ) ; uy = ( long ) ( g.scale * g.objects[ i ].mass * 70.0 ) ; linelong( mainview , xx + ux , yy + ty , xx - ux , yy + ty ) ; linelong( mainview , xx - ux , yy + ty , xx - tx , yy + uy ) ; linelong( mainview , xx - tx , yy + uy , xx - tx , yy - uy ) ; linelong( mainview , xx - tx , yy - uy , xx - ux , yy - ty ) ; linelong( mainview , xx - ux , yy - ty , xx + ux , yy - ty ) ; linelong( mainview , xx + ux , yy - ty , xx + tx , yy - uy ) ; linelong( mainview , xx + tx , yy - uy , xx + tx , yy + uy ) ; linelong( mainview , xx + tx , yy + uy , xx + ux , yy + ty ) ; } } } } if ( w == topview ) { SetAPen( topview->RPort , DOTPEN ) ; xx = ( topview->Width >> 1 ) + ( long ) ( g.scale * np.x * 200.0 ) ; yy = ( topview->Height >> 1 ) - ( long ) ( g.scale * -np.z * 177.0 ) ; linelong( topview , xx - 6 , yy , xx + 6 , yy ) ; linelong( topview , xx , yy - 5 , xx , yy + 5 ) ; if ( g.awaiting == NEWVELOCITY ) { SetAPen( topview->RPort , LINEPEN ) ; for( i = 0 ; i < 20 ; i ++ ) { if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) ) { basis( &g.objects[ i ].position , &g.viewbasis , &np ) ; adddv( &np , &g.viewoffset , &np ) ; xx = ( topview->Width >> 1 ) + ( long ) ( g.scale * np.x * 200.0 ) ; yy = ( topview->Height >> 1 ) - ( long ) ( g.scale * -np.z * 177.0 ) ; adddv( &g.objects[ i ].position , &g.objects[ i ].velocity , &np ) ; basis( &np , &g.viewbasis , &vv ) ; adddv( &vv , &g.viewoffset , &vv ) ; tx = ( topview->Width >> 1 ) + ( long ) ( g.scale * vv.x * 200.0 ) ; ty = ( topview->Height >> 1 ) - ( long ) ( g.scale * -vv.z * 177.0 ) ; linelong( topview , xx , yy , tx , ty ) ; } } } else if ( g.awaiting == NEWMASS ) { SetAPen( topview->RPort , LINEPEN ) ; for( i = 0 ; i < 20 ; i ++ ) { if ( ( g.objects[ i ].flags ) && ( g.objects[ i ].mass ) && ( ! g.objects[ i ].collision ) ) { basis( &g.objects[ i ].position , &g.viewbasis , &np ) ; adddv( &np , &g.viewoffset , &np ) ; xx = ( topview->Width >> 1 ) + ( long ) ( g.scale * np.x * 200.0 ) ; yy = ( topview->Height >> 1 ) - ( long ) ( g.scale * -np.z * 177.0 ) ; tx = ( long ) ( g.scale * g.objects[ i ].mass * 200.0 ) ; ty = ( long ) ( g.scale * g.objects[ i ].mass * 177.0 ) ; ux = ( long ) ( g.scale * g.objects[ i ].mass * 80.0 ) ; uy = ( long ) ( g.scale * g.objects[ i ].mass * 70.0 ) ; linelong( topview , xx + ux , yy + ty , xx - ux , yy + ty ) ; linelong( topview , xx - ux , yy + ty , xx - tx , yy + uy ) ; linelong( topview , xx - tx , yy + uy , xx - tx , yy - uy ) ; linelong( topview , xx - tx , yy - uy , xx - ux , yy - ty ) ; linelong( topview , xx - ux , yy - ty , xx + ux , yy - ty ) ; linelong( topview , xx + ux , yy - ty , xx + tx , yy - uy ) ; linelong( topview , xx + tx , yy - uy , xx + tx , yy + uy ) ; linelong( topview , xx + tx , yy + uy , xx + ux , yy + ty ) ; } } } } if ( w == rightview ) { SetAPen( rightview->RPort , DOTPEN ) ; xx = ( rightview->Width >> 1 ) + ( long ) ( g.scale * -np.z * 200.0 ) ; yy = ( rightview->Height >> 1 ) - ( long ) ( g.scale * np.y * 177.0 ) ; linelong( rightview , xx - 6 , yy , xx + 6 , yy ) ; linelong( rightview , xx , yy - 5 , xx , yy + 5 ) ; if ( g.awaiting == NEWVELOCITY ) { SetAPen( rightview->RPort , LINEPEN ) ; for( i = 0 ; i < 20 ; i ++ ) { if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) ) { basis( &g.objects[ i ].position , &g.viewbasis , &np ) ; adddv( &np , &g.viewoffset , &np ) ; xx = ( rightview->Width >> 1 ) + ( long ) ( g.scale * -np.z * 200.0 ) ; yy = ( rightview->Height >> 1 ) - ( long ) ( g.scale * np.y * 177.0 ) ; adddv( &g.objects[ i ].position , &g.objects[ i ].velocity , &np ) ; basis( &np , &g.viewbasis , &vv ) ; adddv( &vv , &g.viewoffset , &vv ) ; tx = ( rightview->Width >> 1 ) + ( long ) ( g.scale * -vv.z * 200.0 ) ; ty = ( rightview->Height >> 1 ) - ( long ) ( g.scale * vv.y * 177.0 ) ; linelong( rightview , xx , yy , tx , ty ) ; } } } else if ( g.awaiting == NEWMASS ) { SetAPen( rightview->RPort , LINEPEN ) ; for( i = 0 ; i < 20 ; i ++ ) { if ( ( g.objects[ i ].flags ) && ( g.objects[ i ].mass ) && ( ! g.objects[ i ].collision ) ) { basis( &g.objects[ i ].position , &g.viewbasis , &np ) ; adddv( &np , &g.viewoffset , &np ) ; xx = ( rightview->Width >> 1 ) + ( long ) ( g.scale * -np.z * 200.0 ) ; yy = ( rightview->Height >> 1 ) - ( long ) ( g.scale * np.y * 177.0 ) ; tx = ( long ) ( g.scale * g.objects[ i ].mass * 200.0 ) ; ty = ( long ) ( g.scale * g.objects[ i ].mass * 177.0 ) ; ux = ( long ) ( g.scale * g.objects[ i ].mass * 80.0 ) ; uy = ( long ) ( g.scale * g.objects[ i ].mass * 70.0 ) ; linelong( rightview , xx + ux , yy + ty , xx - ux , yy + ty ) ; linelong( rightview , xx - ux , yy + ty , xx - tx , yy + uy ) ; linelong( rightview , xx - tx , yy + uy , xx - tx , yy - uy ) ; linelong( rightview , xx - tx , yy - uy , xx - ux , yy - ty ) ; linelong( rightview , xx - ux , yy - ty , xx + ux , yy - ty ) ; linelong( rightview , xx + ux , yy - ty , xx + tx , yy - uy ) ; linelong( rightview , xx + tx , yy - uy , xx + tx , yy + uy ) ; linelong( rightview , xx + tx , yy + uy , xx + ux , yy + ty ) ; } } } } } for ( i = 0 ; i < 20 ; i ++ ) { if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) ) { if ( g.follow ) { subdv( &g.objects[ i ].position , &g.objects[ g.objectnum ].position , &vv ) ; basis( &vv , &g.viewbasis , &np ) ; } else { basis( &g.objects[ i ].position , &g.viewbasis , &np ) ; adddv( &np , &g.viewoffset , &np ) ; } SetAPen( w->RPort , DOTPEN ) ; if ( w == mainview ) pixel( w , np.x , np.y ) ; if ( w == topview ) pixel( w , np.x , -np.z ) ; if ( w == rightview ) pixel( w , -np.z , np.y ) ; } } } void set() { long i ; g.elapsedtime = 0 ; for ( i = 0 ; i < 20 ; i ++ ) { g.objects[ i ].startmass = g.objects[ i ].mass ; g.objects[ i ].startpos = g.objects[ i ].position ; g.objects[ i ].oldpos = g.objects[ i ].position ; g.objects[ i ].startvel = g.objects[ i ].velocity ; if ( g.objects[ i ].collision ) deleteobject( i ) ; } setstrings() ; } void create() { g.objects[ g.objectnum ].flags = 1 ; g.objects[ g.objectnum ].collision = 0 ; Move( control->RPort , 48 , 21 + ( g.objectnum * 14 ) ) ; Text( control->RPort , "*" , 1 ) ; } void setstrings() { char *p ; controlinfo[ 3 ].Buffer = &g.objects[ g.objectnum ].name[ 0 ] ; p = gcvt( g.timestep , DBL_DIG , &numberbuff[ 0 ][ 0 ] ) ; p = gcvt( g.magic , DBL_DIG , &numberbuff[ 1 ][ 0 ] ) ; p = gcvt( g.objects[ g.objectnum ].mass , DBL_DIG , &numberbuff[ 2 ][ 0 ] ) ; p = gcvt( g.objects[ g.objectnum ].radius , DBL_DIG , &numberbuff[ 3 ][ 0 ] ) ; p = gcvt( g.objects[ g.objectnum ].startpos.x , DBL_DIG , &numberbuff[ 4 ][ 0 ] ) ; p = gcvt( g.objects[ g.objectnum ].startpos.y , DBL_DIG , &numberbuff[ 6 ][ 0 ] ) ; p = gcvt( g.objects[ g.objectnum ].startpos.z , DBL_DIG , &numberbuff[ 8 ][ 0 ] ) ; p = gcvt( g.objects[ g.objectnum ].startvel.x , DBL_DIG , &numberbuff[ 5 ][ 0 ] ) ; p = gcvt( g.objects[ g.objectnum ].startvel.y , DBL_DIG , &numberbuff[ 7 ][ 0 ] ) ; p = gcvt( g.objects[ g.objectnum ].startvel.z , DBL_DIG , &numberbuff[ 9 ][ 0 ] ) ; RefreshGadgets( &controlgadg[ 31 ] , control , NULL ) ; } void deleteobject( num ) long num ; { Move( control->RPort , 48 , 21 + ( num * 14 ) ) ; Text( control->RPort , " " , 1 ) ; g.objects[ num ].flags = 0 ; g.objects[ num ].collision = 0 ; g.objects[ num ].position = zerodv ; g.objects[ num ].startpos = zerodv ; g.objects[ num ].velocity = zerodv ; g.objects[ num ].startvel = zerodv ; g.objects[ num ].oldpos = zerodv ; g.objects[ num ].mass = 0.0 ; g.objects[ num ].startmass = 0.0 ; g.objects[ num ].radius = 0.0 ; g.objects[ num ].name[ 0 ] = 0 ; } void endtrail( i , j ) long i , j ; { struct dv op , tv ; if ( g.trailson ) { if ( mainview ) SetAPen( mainview->RPort , LINEPEN ) ; if ( topview ) SetAPen( topview->RPort , LINEPEN ) ; if ( rightview ) SetAPen( rightview->RPort , LINEPEN ) ; } else { if ( mainview ) SetAPen( mainview->RPort , 0 ) ; if ( topview ) SetAPen( topview->RPort , 0 ) ; if ( rightview ) SetAPen( rightview->RPort , 0 ) ; } if ( g.follow ) { subdv( &g.objects[ i ].oldpos , &g.objects[ g.objectnum ].oldpos , &tv ) ; basis( &tv , &g.viewbasis , &op ) ; } else { basis( &g.objects[ i ].oldpos , &g.viewbasis , &tv ) ; adddv( &tv , &g.viewoffset , &op ) ; } if ( mainview ) pixel( mainview , op.x , op.y ) ; if ( topview ) pixel( topview , op.x , -op.z ) ; if ( rightview ) pixel( rightview , -op.z , op.y ) ; if ( g.follow ) { subdv( &g.objects[ j ].oldpos , &g.objects[ g.objectnum ].oldpos , &tv ) ; basis( &tv , &g.viewbasis , &op ) ; } else { basis( &g.objects[ j ].oldpos , &g.viewbasis , &tv ) ; adddv( &tv , &g.viewoffset , &op ) ; } if ( mainview ) pixel( mainview , op.x , op.y ) ; if ( topview ) pixel( topview , op.x , -op.z ) ; if ( rightview ) pixel( rightview , -op.z , op.y ) ; } void updatedisplay() { struct dv np[ 20 ] , op[ 20 ] , tv ; long i ; char *p ; if ( g.trailson ) { if ( mainview ) SetAPen( mainview->RPort , LINEPEN ) ; if ( topview ) SetAPen( topview->RPort , LINEPEN ) ; if ( rightview ) SetAPen( rightview->RPort , LINEPEN ) ; } else { if ( mainview ) SetAPen( mainview->RPort , 0 ) ; if ( topview ) SetAPen( topview->RPort , 0 ) ; if ( rightview ) SetAPen( rightview->RPort , 0 ) ; } for ( i = 0 ; i < 20 ; i ++ ) { if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) ) { if ( g.follow ) { subdv( &g.objects[ i ].position , &g.objects[ g.objectnum ].position , &tv ) ; basis( &tv , &g.viewbasis , &np[ i ] ) ; subdv( &g.objects[ i ].oldpos , &g.objects[ g.objectnum ].oldpos , &tv ) ; basis( &tv , &g.viewbasis , &op[ i ] ) ; } else { basis( &g.objects[ i ].position , &g.viewbasis , &tv ) ; adddv( &tv , &g.viewoffset , &np[ i ] ) ; basis( &g.objects[ i ].oldpos , &g.viewbasis , &tv ) ; adddv( &tv , &g.viewoffset , &op[ i ] ) ; } if ( mainview ) pixel( mainview , op[ i ].x , op[ i ].y ) ; if ( topview ) pixel( topview , op[ i ].x , -op[ i ].z ) ; if ( rightview ) pixel( rightview , -op[ i ].z , op[ i ].y ) ; } } if ( g.trailson ) { if ( mainview ) SetAPen( mainview->RPort , LINEPEN ) ; if ( topview ) SetAPen( topview->RPort , LINEPEN ) ; if ( rightview ) SetAPen( rightview->RPort , LINEPEN ) ; for ( i = 0 ; i < 20 ; i ++ ) { if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) ) { if ( mainview ) line( mainview , op[ i ].x , op[ i ].y , np[ i ].x , np[ i ].y ) ; if ( topview ) line( topview , op[ i ].x , -op[ i ].z , np[ i ].x , -np[ i ].z ) ; if ( rightview ) line( rightview , -op[ i ].z , op[ i ].y , -np[ i ].z , np[ i ].y ) ; } } } if ( mainview ) SetAPen( mainview->RPort , DOTPEN ) ; if ( topview ) SetAPen( topview->RPort , DOTPEN ) ; if ( rightview ) SetAPen( rightview->RPort , DOTPEN ) ; for ( i = 0 ; i < 20 ; i ++ ) { if ( g.objects[ i ].flags && ( ! g.objects[ i ].collision ) ) { if ( mainview ) pixel( mainview , np[ i ].x , np[ i ].y ) ; if ( topview ) pixel( topview , np[ i ].x , -np[ i ].z ) ; if ( rightview ) pixel( rightview , -np[ i ].z , np[ i ].y ) ; } } p = gcvt( g.elapsedtime , DBL_DIG , &ettext[ 0 ] ) ; Move( control->RPort , 234 , 211 ) ; Text( control->RPort , &ettext[ 0 ] , strlen( &ettext[ 0 ] ) ) ; Text( control->RPort , " " , 16 ) ; }