//This requires a JoyStick. Button 2 engages //a anti-spin control. $PI,"",2$ $PI,"",4$ $PI,"",5$ $PI,"",6$ $PI,"",7$ class Ship { double x,y,theta,DxDt,DyDt,DthetaDt; }; U8 destroyed_time; U8 phasor_time; U4 updates=0; U1 *img1=$IB,"",2$; U1 *img2=$IB,"",4$; U1 *img3=$IB,"",5$; U1 *img4=$IB,"",6$; U1 *img5=$IB,"",7$; GrBitMap *base; Ode *o; Order2D3 *enemy_state; Ship *enterprise_state; #define NUM_STARS 100 I8 stars_x[NUM_STARS],stars_y[NUM_STARS]; void PhasorTsk() { while (phasor_time) { Sound(DivI8(MulI8(4000,phasor_time-jiffies),JIFFY_FREQ)); Sleep(1); } Sound(0); } void BoomTsk() { I2 i; for (i=2000;i>100;i=i-3) { Sound(100+100*(i&1)); Sleep(1); } Sound(0); } #define MAX_SPIN_THRUST 25.0 void MyDerivative(Ode *o,double t,Order2D3 *state,Order2D3 *DstateDt) { Order2D3 *enemy_state=state; Ship *enterprise_state=state+sizeof(Order2D3); Order2D3 *Denemy_state=DstateDt; Ship *Denterprise_state=DstateDt+sizeof(Order2D3); double dx,dy,d,f; I8 jx=DivI8(MulI8(150,joyv[0]-joyrest[0]),joymax[0]-joymin[0]+1); I8 jy=DivI8(MulI8(150,joyv[1]-joyrest[1]),joymax[1]-joymin[1]+1); double mag,Dtheta; R2P(&mag,&Dtheta,jx,-jy); o;t; //avoid unused var warning dx=grwidth/2-enemy_state->x; dy=grheight/2-enemy_state->y; d=Sqr(dx)+Sqr(dy); f=1e6/(d+50); d=Sqrt(d); Denemy_state->x=enemy_state->DxDt; Denemy_state->y=enemy_state->DyDt; Denemy_state->DxDt=f*dx/d; Denemy_state->DyDt=f*dy/d; dx=grwidth/2-enterprise_state->x; dy=grheight/2-enterprise_state->y; d=Sqr(dx)+Sqr(dy); f=1e6/(d+50); d=Sqrt(d); Denterprise_state->x=enterprise_state->DxDt; Denterprise_state->y=enterprise_state->DyDt; Denterprise_state->theta=enterprise_state->DthetaDt; //Convert to heading and ignore joystick at rest Dtheta=(Abs(mag)<25.0) ? 0.0:MAX_SPIN_THRUST*Unwrap(pi/2-Dtheta)/pi; Denterprise_state->DthetaDt=Dtheta; if (Abs(Dtheta)>1) mag=0; //Only thrust when joystick pushed up, more or less Denterprise_state->DxDt=f*dx/d+mag*Cos(enterprise_state->theta); Denterprise_state->DyDt=f*dy/d+mag*Sin(enterprise_state->theta); if (joyb[1]) { Dtheta=enterprise_state->DthetaDt; if (Abs(Dtheta)>MAX_SPIN_THRUST) Dtheta=Sign(Dtheta)*MAX_SPIN_THRUST; Denterprise_state->DthetaDt=-Dtheta; } } void DrawIt() { U8 i; I8 *r1,x,y,z; double jx=(joyv[0]-joyrest[0])*150.0/(joymax[0]-joymin[0]+1); double jy=(joyv[1]-joyrest[1])*150.0/(joymax[1]-joymin[1]+1); double theta=enterprise_state->theta; ClearWindowText; base->color=GR_WHITE; for (i=0;ix=enterprise_state->x; base->y=enterprise_state->y; base->z=0; base->flags|=BMF_TRANSFORMATION; r1=base->r; base->r=GrTheta(theta); GrElemsPlot(base,0,0,0,img1,GR_BLACK); if (phasor_time) { if (updates & 1) base->color=GR_YELLOW; else base->color=GR_RED; GrLine2(base,75,0,0,300,0,0); if (jiffies>=phasor_time) phasor_time=0; x=300,y=0,z=0; GrTransform(base,&x,&y,&z); if (!destroyed_time && Abs(x-enemy_state->x)<50.0 && Abs(y-enemy_state->y)<50.0) { destroyed_time=jiffies+JIFFY_FREQ; //one second Spawn(&BoomTsk); } } Free(base->r); base->r=r1; base->flags&=~BMF_TRANSFORMATION; if (destroyed_time) { GrElemsPlot(base,enemy_state->x,enemy_state->y,0,img3,GR_BLACK); if (jiffies>=destroyed_time) destroyed_time=0; } else GrElemsPlot(base,enemy_state->x,enemy_state->y,0,img2,GR_BLACK); if (updates++ & 2) GrElemsPlot(base,grwidth/2,grheight/2,0,img4,GR_BLACK); else GrElemsPlot(base,grwidth/2,grheight/2,0,img5,GR_BLACK); if (enterprise_state->x>grwidth) enterprise_state->x-=grwidth; if (enterprise_state->x<0) enterprise_state->x+=grwidth; if (enterprise_state->y>grheight) enterprise_state->y-=grheight; if (enterprise_state->y<0) enterprise_state->y+=grheight; if (enemy_state->x>grwidth) enemy_state->x-=grwidth; if (enemy_state->x<0) enemy_state->x+=grwidth; if (enemy_state->y>grheight) enemy_state->y-=grheight; if (enemy_state->y<0) enemy_state->y+=grheight; } void StarTrek3() { U8 i; U8 old_ip=ip_pointer_type,sc,ch=0; U4 *old_update_window=Fs->update_window; U4 old_text_attr=Fs->text_attribute; BoolU4 old_preempt; destroyed_time=0; phasor_time=0; base=GrNew(grbase2); o=OdeNew(12); enemy_state=o->state; enterprise_state=o->state+sizeof(Order2D3); o->derivative=&MyDerivative; o->tolerance_start=.1; ip_pointer_type=IP_JOYSTICK0; ip_inhibit_win_operations=TRUE; LoadJoystickCalibration; Fs->text_attribute=0; Fs->update_window=&DrawIt; MaximizeWindow; enemy_state->x=100; enemy_state->y=100; enemy_state->DxDt=10.0; enemy_state->DyDt=20.0; enterprise_state->x=300; enterprise_state->y=100; enterprise_state->DxDt=10.0; enterprise_state->DyDt=20.0; old_preempt=Preempt(OFF); InsQue(o,Fs->last_ode); Preempt(old_preempt); for (i=0;iupdate_window=old_update_window; Fs->text_attribute=old_text_attr; ip_pointer_type=old_ip; ip_inhibit_win_operations=FALSE; LtfBottom(Fs->cur_ltf); } StarTrek3; ­6¡ÿÿÿÒÿÿÿ[gÛ®m’d’$IÛvÛFaûö:@L�ÿÿÿèÿÿÿ$ýÛ¶m{^‚ @’$±}ÿ÷“$Ù’$q=×¶Móô““ÿÿÿóÿÿÿ$I’$I’äù“ ýÿÿÿæÿÿÿøÿÿÿýÿÿÿÚÿÿÿèÿÿÿž}ÿÿÿµ‘Ä÷oºðÿÿÿÛÖmݺ­[·¹m[×¶mÿÿÏÿüO“$M’”DI’$IR¢„I’$À0`À¶mÛ¶ÍÛ¶uۼ͔Úv­ëHR$J’(’$É“çIû¿éÛ¾m»mݶÝ6 CI’$’¶ý¶Ýºuݺn]·®[×Í‚$ EQÅß6I’$I’–IIÛÖÖ¶mÛ$/Š’DIJ’`¶mmÛ¶Ý6Ì7yúÿïÛæO& @@HJ òÿÿÿåÿÿÿ  ùÿÿÿ!÷ÿÿÿîÿÿÿøÿÿÿäÿÿÿøÿÿÿöÿÿÿêÿÿÿëÿÿÿøÿÿÿÿÿÿÿòÿÿÿþÿÿÿõÿÿÿåÿÿÿýÿÿÿ ž}ÿÿÿµ‘Ä÷oºðÿÿÿÛÖmݺ­[·¹m[×¶mÿÿÏÿüO“$M’”DI’$IR¢„I’$À0`À¶mÛ¶ÍÛ¶uۼ͔Úv­ëHR$J’(’$É“çIû¿éÛ¾m»mݶÝ6 CI’$’¶ý¶Ýºuݺn]·®[×Í‚$ EQÅß6I’$I’–IIÛÖÖ¶mÛ$/Š’DIJ’`¶mmÛ¶Ý6Ì7yúÿïÛæO& @@HJùÿÿÿ ãÿÿÿûÿÿÿ ýÿÿÿöÿÿÿûÿÿÿêÿÿÿìÿÿÿöÿÿÿþÿÿÿÕÿÿÿúÿÿÿóÿÿÿóÿÿÿÿÿÿÿûÿÿÿøÿÿÿáÿÿÿøÿÿÿüÿÿÿ