Team Ai
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes847downloads
Varoom.txt705 linesDownload Raw Back to Games
1 2 3 4 5 6 7    <1>/* Graphics Not Rendered in HTML */8 9 10 11    <2>/* Graphics Not Rendered in HTML */12 13 14 15 16 17 18 19    <3>/* Graphics Not Rendered in HTML */20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40    <4>/* Graphics Not Rendered in HTML */41 42 43 44 45 46 47 48 49 50                 <5>/* Graphics Not Rendered in HTML */51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78                 <6>/* Graphics Not Rendered in HTML */79 80 81 82 83 84 85 86 87 88 89 90 91RegDft("TempleOS/Varoom","F64 best_score=9999;\n");92RegExe("TempleOS/Varoom");93 94F64 distance,t0,tf;95Bool game_over;96 97#define BORDER          750098#define RADIUS          1000099#define WIDTH           2000100#define SHOULDER        200101#define D_theta         (2*pi/360)   //Curve track slice is one degree.102#define D_S             (2*pi*RADIUS/360) //Straight track is degree at 10000.103#define DIPS            5104#define DIP_DEPTH       50105class Track106{107  Track *next,*last;108  I32 num;109  CColorROPU16 c,pad;110  I64 x,z;111  F64 theta,d;112  CD3I32 left[4],center[4],right[4];113} track_head,114  *track_start[MP_PROCESSORS_NUM],*track_end[MP_PROCESSORS_NUM];115 116CDC *track_map;117#define MAP_BITS        9118I64 t_minx,t_maxx,t_minz,t_maxz;119 120#define BUSHES_NUM      512121class Bush122{123  CD3I32 p;124  Bool sym,pad[3];125  U8 *img;126} b[BUSHES_NUM];127 128#define CARS_NUM        8129class Car130{131  CD3I32 p;132  F64 theta,dtheta,speed;133  U8 *img;134  Track *t;135} c[CARS_NUM];136 137I64 DipY(I64 x,I64 z)138{139  F64 m,a;140  R2P(&m,&a,x,z);141  return DIP_DEPTH*m*Cos(DIPS*a)/RADIUS;142}143 144#define CAR_LENGTH      400145 146F64 Diptheta(I64 x,I64 z,F64 theta)147{148  F64 y_front,y_back;149  y_front=DipY(x-CAR_LENGTH/2*Cos(theta),z-CAR_LENGTH/2*Sin(theta));150  y_back =DipY(x+CAR_LENGTH/2*Cos(theta),z+CAR_LENGTH/2*Sin(theta));151  return ASin((y_front-y_back)/CAR_LENGTH);152}153 154Track *TrackFind(Track *_tmpt,I64 x,I64 z)155{156  Track *res=_tmpt,*tmpt;157  I64 dd,best=SqrI64(res->x-x)+SqrI64(res->z-z);158 159  tmpt=_tmpt;160  while (TRUE) {161    tmpt=tmpt->next;162    if (tmpt==&track_head)163      tmpt=tmpt->next;164    dd=SqrI64(tmpt->x-x)+SqrI64(tmpt->z-z);165    if (dd<best) {166      best=dd;167      res=tmpt;168    } else169      break;170  }171  tmpt=_tmpt;172  while (TRUE) {173    tmpt=tmpt->last;174    if (tmpt==&track_head)175      tmpt=tmpt->last;176    dd=SqrI64(tmpt->x-x)+SqrI64(tmpt->z-z);177    if (dd<best) {178      best=dd;179      res=tmpt;180    } else181      break;182  }183  return res;184}185 186U0 TrackSlice(F64 *_x,F64 *_z,F64 theta,F64 d)187{188  F64 x=*_x,z=*_z,c=Cos(theta),s=Sin(theta),dx=d*s,dz=-d*c;189  Track *tmpt,*last=track_head.last;190  if (last==&track_head)191    last=NULL;192 193  tmpt=CAlloc(sizeof(Track));194  if (last) {195    MemCpy(&tmpt->center[0],&last->center[3],sizeof(CD3I32));196    MemCpy(&tmpt->center[1],&last->center[2],sizeof(CD3I32));197  }198  tmpt->center[2].x=x+(WIDTH/2)*c+dx;199  tmpt->center[2].z=z+(WIDTH/2)*s+dz;200  tmpt->center[2].y=DipY(tmpt->center[2].x,tmpt->center[2].z);201  tmpt->center[3].x=x-(WIDTH/2)*c+dx;202  tmpt->center[3].z=z-(WIDTH/2)*s+dz;203  tmpt->center[3].y=DipY(tmpt->center[3].x,tmpt->center[3].z);204 205  if (last) {206    MemCpy(&tmpt->left[0],&last->left[3],sizeof(CD3I32));207    MemCpy(&tmpt->left[1],&last->left[2],sizeof(CD3I32));208  }209  tmpt->left[2].x=x-(WIDTH/2)*c+dx;210  tmpt->left[2].z=z-(WIDTH/2)*s+dz;211  tmpt->left[2].y=DipY(tmpt->left[2].x,tmpt->left[2].z);212  tmpt->left[3].x=x-(WIDTH/2+SHOULDER)*c+dx;213  tmpt->left[3].z=z-(WIDTH/2+SHOULDER)*s+dz;214  tmpt->left[3].y=DipY(tmpt->left[3].x,tmpt->left[3].z);215 216  if (last) {217    MemCpy(&tmpt->right[0],&last->right[3],sizeof(CD3I32));218    MemCpy(&tmpt->right[1],&last->right[2],sizeof(CD3I32));219  }220  tmpt->right[2].x=x+(WIDTH/2+SHOULDER)*c+dx;221  tmpt->right[2].z=z+(WIDTH/2+SHOULDER)*s+dz;222  tmpt->right[2].y=DipY(tmpt->right[2].x,tmpt->right[2].z);223  tmpt->right[3].x=x+(WIDTH/2)*c+dx;224  tmpt->right[3].z=z+(WIDTH/2)*s+dz;225  tmpt->right[3].y=DipY(tmpt->right[3].x,tmpt->right[3].z);226 227  tmpt->x=x;228  tmpt->z=z;229  tmpt->theta=theta;230  tmpt->num=track_head.last->num+1;231  tmpt->d  =track_head.last->d+d;232 233  QueIns(tmpt,track_head.last);234 235  if (tmpt->num&1)236    tmpt->c=RED;237  else238    tmpt->c=WHITE;239 240  if (x<t_minx) t_minx=x;241  if (x>t_maxx) t_maxx=x;242  if (z<t_minz) t_minz=z;243  if (z>t_maxz) t_maxz=z;244 245  x+=dx;246  *_x=x;247  z+=dz;248  *_z=z;249 250  if (x<t_minx) t_minx=x;251  if (x>t_maxx) t_maxx=x;252  if (z<t_minz) t_minz=z;253  if (z>t_maxz) t_maxz=z;254}255 256U0 CoupleEnds()257{258  Track *first=track_head.next,*last=track_head.last;259  MemCpy(&first->center[0],&last->center[3],sizeof(CD3I32));260  MemCpy(&first->center[1],&last->center[2],sizeof(CD3I32));261  MemCpy(&first->left[0]  ,&last->left[3]  ,sizeof(CD3I32));262  MemCpy(&first->left[1]  ,&last->left[2]  ,sizeof(CD3I32));263  MemCpy(&first->right[0] ,&last->right[3] ,sizeof(CD3I32));264  MemCpy(&first->right[1] ,&last->right[2] ,sizeof(CD3I32));265}266 267U0 InitTrack()268{269  I64 i,j;270  Track *tmpt;271  F64 x,z,theta,d;272 273  MemSet(&track_head,0,sizeof(Track));274  QueInit(&track_head);275 276  t_minx=t_minz=I64_MAX;277  t_maxx=t_maxz=I64_MIN;278 279  x=0; z=0; theta=0;280  for (d=0;d<6*RADIUS;d+=D_S)281    TrackSlice(&x,&z,theta,D_S);282  for (i=0;i<180;i++,theta+=D_theta)283    TrackSlice(&x,&z,theta,D_theta*RADIUS);284  for (d=0;d<RADIUS;d+=D_S)285    TrackSlice(&x,&z,theta,D_S);286  for (i=0;i<90;i++,theta-=D_theta)287    TrackSlice(&x,&z,theta,D_theta*RADIUS);288  for (i=0;i<180;i++,theta+=D_theta)289    TrackSlice(&x,&z,theta,D_theta*RADIUS);290  for (i=0;i<90;i++,theta-=D_theta)291    TrackSlice(&x,&z,theta,D_theta*RADIUS);292  for (d=0;d<RADIUS;d+=D_S)293    TrackSlice(&x,&z,theta,D_S);294  for (i=0;i<180;i++,theta+=D_theta)295    TrackSlice(&x,&z,theta,D_theta*RADIUS);296 297  CoupleEnds;298 299  tmpt=track_head.next;300  for (i=0;i<mp_cnt;i++) {301    j=(i+1)*track_head.last->num/mp_cnt+1;302    track_start[i]=tmpt;303    while (tmpt!=&track_head && tmpt->num!=j)304      tmpt=tmpt->next;305    track_end[i]=tmpt;306  }307 308  t_minx-=BORDER; t_minz-=BORDER;309  t_maxx+=BORDER; t_maxz+=BORDER;310  track_map=DCNew((t_maxx-t_minx+1<<MAP_BITS-1)>>MAP_BITS,311        (t_maxz-t_minz+1<<MAP_BITS-1)>>MAP_BITS);312 313  track_map->color=LTGRAY;314  GrRect(track_map,0,0,track_map->width,track_map->height);315  tmpt=track_head.next;316  track_map->color=YELLOW;317  track_map->thick=3;318  while (tmpt!=&track_head) {319    GrPlot3(track_map,track_map->width-(tmpt->x-t_minx)>>MAP_BITS,320          (tmpt->z-t_minz)>>MAP_BITS,0);321    tmpt=tmpt->next;322  }323}324 325#define HORIZON_DIP     200326 327Bool PrepPoly(CD3I32 *p,I64 *r,I64 cx,I64 h,CD3I32 *poly)328{329  I64 x,y,z,i;330  F64 s;331  for (i=0;i<4;i++) {332    x=p[i].x-c[0].p.x;333    y=p[i].y-c[0].p.y;334    z=p[i].z-c[0].p.z;335    Mat4x4MulXYZ(r,&x,&y,&z);336    s=100.0/(AbsI64(z)+50);337    poly[i].y=s*y+h;338    if (z<-200 || !(-h<poly[i].y<2*h))339      return FALSE;340    poly[i].x=s*x+cx;341    poly[i].z=z+GR_Z_ALL;342  }343  return TRUE;344}345 346I64 mp_not_done_flags;347 348U0 MPUpdateWin(CDC *dc2)349{350  CTask *task=dc2->win_task;351  I64   i,x,y,z,352        w=task->pix_width,h=task->pix_height,r[16],cx=w>>1;353  F64   s,dip_theta=Diptheta(c[0].p.x,c[0].p.z,c[0].theta);354  Car   *tmpc;355  CD3I32 poly[4];356  Track *tmpt,*tmpt1;357  CDC   *dc=DCAlias(gr.dc2,task);358 359  Mat4x4IdentEqu(r);360  Mat4x4RotY(r,pi-c[0].theta);361  Mat4x4RotX(r,75*pi/180-dip_theta);362 363  dc->depth_buf=dc2->depth_buf;364 365  //Track366  tmpt =track_start[Gs->num];367  tmpt1=track_end  [Gs->num];368  while (tmpt!=tmpt1) {369    dc->color=DKGRAY;370    if (PrepPoly(&tmpt->center,r,cx,h,poly)) {371      GrFillPoly3(dc,4,poly);372      dc->color=tmpt->c;373      if (PrepPoly(&tmpt->left,r,cx,h,poly))374        GrFillPoly3(dc,4,poly);375      if (PrepPoly(&tmpt->right,r,cx,h,poly))376        GrFillPoly3(dc,4,poly);377    }378    tmpt=tmpt->next;379  }380 381  dc->flags|=DCF_TRANSFORMATION;382  for (i=Gs->num;i<BUSHES_NUM;i+=mp_cnt) {383    x=b[i].p.x-c[0].p.x; y=b[i].p.y-c[0].p.y; z=b[i].p.z-c[0].p.z;384    Mat4x4MulXYZ(r,&x,&y,&z);385    if (z>0) {386      s=100.0/(AbsI64(z)+50);387      Mat4x4IdentEqu(dc->r);388      Mat4x4Scale(dc->r,s*2);389      DCMat4x4Set(dc,dc->r);390      if (b[i].sym) {391        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;392        DCSymmetrySet(dc,s*x+cx,s*y+h,s*x+cx,s*y+h+10);393      }394      Sprite3B(dc,s*x+cx,s*y+h,z+GR_Z_ALL,b[i].img);395      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);396    }397  }398  for (i=Gs->num+1;i<CARS_NUM;i+=mp_cnt) {399    tmpc=&c[i];400    x=tmpc->p.x-c[0].p.x; y=tmpc->p.y-c[0].p.y; z=tmpc->p.z-c[0].p.z;401    Mat4x4MulXYZ(r,&x,&y,&z);402    if (z>0) {403      s=100.0/(AbsI64(z)+50);404      Mat4x4IdentEqu(dc->r);405      Mat4x4Scale(dc->r,s*2);406      Mat4x4RotX(dc->r,Diptheta(tmpc->p.x,tmpc->p.z,-tmpc->theta));407      Mat4x4RotY(dc->r,tmpc->theta-c[0].theta);408      DCMat4x4Set(dc,dc->r);409      Sprite3B(dc,s*x+cx,s*y+h,z+GR_Z_ALL,tmpc->img);410    }411  }412  dc->depth_buf=NULL;413  DCDel(dc);414  LBtr(&mp_not_done_flags,Gs->num);415}416 417U0 VRTransform(CDC *dc,I64 *x,I64 *y,I64 *z)418{419  I64 zz;420  Mat4x4MulXYZ(dc->r,x,y,z);421  zz=400+*z;422  if (zz<1) zz=1;423  *x=400* *x/zz;424  *y=400* *y/zz;425  *x+=dc->x;426  *y+=dc->y;427  *z+=dc->z;428}429 430U0 DrawIt(CTask *task,CDC *dc)431{432  I64   i,x,y,z,433        w=task->pix_width,434        h=task->pix_height,r[16],435        cx=w>>1;436  F64   s,dip_theta=Diptheta(c[0].p.x,c[0].p.z,c[0].theta);437  Car   *tmpc=&c[0];438 439  dc->color=LTCYAN;440  GrRect(dc,0,0,w,HORIZON_DIP*Sin(dip_theta)+FONT_HEIGHT*4.5);441 442  Mat4x4IdentEqu(r);443  Mat4x4RotY(r,pi-c[0].theta);444  Mat4x4RotX(r,75*pi/180-dip_theta);445 446  DCDepthBufAlloc(dc);447 448  //Sun449  x=c[0].p.x; y=0; z=1000000-c[0].p.z;450  Mat4x4MulXYZ(r,&x,&y,&z);451  s=100.0/(AbsI64(z)+50);452  if (y<0) {453    dc->color=BROWN;454    GrCircle(dc,s*x+cx,15+HORIZON_DIP*Sin(dip_theta),15);455    dc->color=YELLOW;456    GrFloodFill(dc,s*x+cx,15+HORIZON_DIP*Sin(dip_theta));457  }458 459  mp_not_done_flags=1<<mp_cnt-1;460  for (i=0;i<mp_cnt;i++)461    JobQue(&MPUpdateWin,dc,i);462  while (mp_not_done_flags)463    Yield;464 465  Mat4x4IdentEqu(r);466  Mat4x4RotY(r,tmpc->dtheta);467  Mat4x4RotX(r,0.4-8*dip_theta); //Made this up468  dc->transform=&VRTransform;469  dc->x=task->pix_width>>1;470  dc->y=task->pix_height-150;471  dc->z=GR_Z_ALL;472  Sprite3Mat4x4B(dc,0,0,-100,c[0].img,r);473 474  //Map475  GrBlot(dc,w-track_map->width,h-track_map->height,track_map);476 477  dc->thick=2;478  for (i=0;i<CARS_NUM;i++) {479    if (i)480      dc->color=LTPURPLE;481    else482      dc->color=LTCYAN;483    GrPlot3(dc,w-(c[i].p.x-t_minx)>>MAP_BITS,484               h-track_map->height+(c[i].p.z-t_minz)>>MAP_BITS,0);485  }486 487  if (game_over) {488    dc->color=LTRED;489    if (tf) {490      s=tf-t0;491      if (Blink)492        GrPrint(dc,(w-FONT_WIDTH*14)/2,(h-FONT_HEIGHT)/2,"Game Completed");493    } else {494      s=99.9;495      if (Blink)496        GrPrint(dc,(w-FONT_WIDTH*9)/2,(h-FONT_HEIGHT)/2,"Game Over");497    }498  } else499    s=tS-t0;500  dc->color=BLACK;501  GrPrint(dc,0,0,"%0.1f%% Time:%0.2f Best:%0.2f",502        100.0*distance/track_head.last->d,s,best_score);503}504 505U0 AnimateTask(I64)506{507  Car  *tmpc;508  I64 i,x,z;509  Bool on_track;510  Track *tmpt,*tmpt2;511  while (TRUE) {512    if (!game_over)513      Snd(12.0*Log2(c[0].speed/500+0.7));514    else515      Snd;516    for (i=0;i<CARS_NUM;i++) {517      tmpc=&c[i];518      tmpc->p.x-=0.01*tmpc->speed*Cos(tmpc->theta-pi/2);519      tmpc->p.z+=0.01*tmpc->speed*Sin(tmpc->theta-pi/2);520      tmpt=TrackFind(tmpc->t,tmpc->p.x,tmpc->p.z);521      if (i) {522        if (tmpt!=tmpc->t) {523          tmpt2=tmpt->next;524          if (tmpt2==&track_head)525            tmpt2=tmpt2->next;526          tmpc->theta=Arg(-tmpt2->z+tmpc->p.z,-tmpt2->x+tmpc->p.x);527        }528      } else {529        tmpc->theta+=0.01*tmpc->dtheta;530        x=track_map->width-(tmpc->p.x-t_minx)>>MAP_BITS;531        z=(tmpc->p.z-t_minz)>>MAP_BITS;532        if (GrPeek(track_map,x,z)!=YELLOW) {533          on_track=FALSE;534          tmpc->speed-=0.01*tmpc->speed;535          if (tmpc->speed<0) tmpc->speed=0;536        } else537          on_track=TRUE;538      }539      tmpc->t=tmpt;540      tmpc->p.y=DipY(tmpc->p.x,tmpc->p.z);541    }542    if (!game_over && on_track) {543      for (i=1;i<CARS_NUM;i++)544        if (D3I32DistSqr(&c[i].p,&c[0].p)<CAR_LENGTH>>1*CAR_LENGTH>>1) {545          game_over=TRUE;546          Noise(500,22,34);547          Sleep(500);548          break;549        }550      if (!game_over) {551        distance+=0.01*c[0].speed;552        if (distance>track_head.last->d&& c[0].t->num<track_head.last->num>>1) {553          tf=tS;554          game_over=TRUE;555          Beep;556          if (tf-t0<best_score) {557            best_score=tf-t0;558            Beep;559          }560        }561      }562    }563    Sleep(10);564  }565}566 567U8 *imgs[8]={<1>,<1>,<2>,<2>,<3>,<4>,<4>,<4>};568 569 570U0 InitBushes()571{572  Bush *tmpb;573  I64 i,j,x,z;574  track_map->color=LTGREEN;575  track_map->thick=1;576  for (i=0;i<BUSHES_NUM;i++) {577    tmpb=&b[i];578 579ib_restart:580    tmpb->p.x=Rand*(t_maxx-t_minx)+t_minx;581    tmpb->p.z=Rand*(t_maxz-t_minz)+t_minz;582    x=track_map->width-(tmpb->p.x-t_minx)>>MAP_BITS;583    z=(tmpb->p.z-t_minz)>>MAP_BITS;584    for (j=0;j<8;j++)585      if (GrPeek(track_map,x+gr_x_offsets[j],z+gr_y_offsets[j])!=LTGRAY)586        goto ib_restart;587 588    GrPlot(track_map,x,z);589    tmpb->p.y=DipY(tmpb->p.x,tmpb->p.z);590    tmpb->sym=RandU16&1;591    tmpb->img=imgs[i&7];592  }593}594 595 596U0 Init()597{598  Car   *tmpc;599  Track *tmpt;600  F64   d;601  I64   i;602 603  InitTrack;604  InitBushes;605  tmpt=track_head.next;606  for (i=0;i<CARS_NUM;i++) {607    tmpc=&c[i];608    tmpc->t=tmpt;609    tmpc->p.x=tmpt->x;610    tmpc->p.z=tmpt->z;611    tmpc->p.y=DipY(tmpc->p.x,tmpc->p.z);612    tmpc->theta  =-tmpt->theta;613    tmpc->dtheta=0;614    if (!i) {615      tmpc->img=<5>;616      tmpc->speed=0;617    } else {618      tmpc->img=<6>;619      tmpc->speed=2500.0;620    }621    d=(i+1)*track_head.last->d/CARS_NUM;622    while (tmpt->next!=&track_head && tmpt->d<d)623      tmpt=tmpt->next;624  }625  distance=0;626  tf=0;627  t0=tS;628  game_over=FALSE;629}630 631U0 CleanUp()632{633  while (mp_not_done_flags)634    Yield;635  QueDel(&track_head,TRUE);636  DCDel(track_map);637}638 639U0 Varoom()640{641  I64 sc;642  MenuPush(643        "File {"644        "  Abort(,CH_SHIFT_ESC);"645        "  Exit(,CH_ESC);"646        "}"647        "Play {"648        "  Restart(,'\n');"649        "  Accelerator(,,SC_CURSOR_UP);"650        "  Brake(,,SC_CURSOR_DOWN);"651        "  Left(,,SC_CURSOR_LEFT);"652        "  Right(,,SC_CURSOR_RIGHT);"653        "}"654        );655  SettingsPush; //See SettingsPush656  try {657    Fs->text_attr=YELLOW<<4+BLUE;658    Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS659          -WIF_SELF_GRAB_SCROLL-WIF_FOCUS_TASK_MENU;660    AutoComplete;661    WinBorder;662    WinMax;663    DocCursor;664    DocClear;665    Init;666    Fs->draw_it=&DrawIt;667    Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);668    while (TRUE)669      switch (GetKey(&sc)) {670        case 0:671          switch (sc.u8[0]) {672            case SC_CURSOR_LEFT:673              c[0].dtheta-=pi/60;674              break;675            case SC_CURSOR_RIGHT:676              c[0].dtheta+=pi/60;677              break;678            case SC_CURSOR_UP:679              c[0].speed+=300;680              break;681            case SC_CURSOR_DOWN:682              c[0].speed-=900;683              if (c[0].speed<0) c[0].speed=0;684              break;685          }686          break;687        case '\n':688          CleanUp;689          Init;690          break;691        case CH_SHIFT_ESC:692        case CH_ESC:693          goto vr_done;694      }695vr_done: //Don't goto out of try696  } catch697    PutExcept;698  SettingsPop;699  CleanUp;700  MenuPop;701  RegWrite("TempleOS/Varoom","F64 best_score=%5.4f;\n",best_score);702}703 704Varoom;705