Team Ai
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes847downloads
LightTable.txt651 linesDownload Raw Back to Graphics
1 2/*3There is a coarse and a fine-grained.4The coarse gets flood-filled but the5fine grained is only outlines.6*/7 8class Photon9{10  Photon *next,*last;11  CD3 p,v,n,p_normal_inhibit;12} p_root[mp_cnt];13I64 p_root_locks;14 15#define ANIMATE_JIFFIES (JIFFY_FREQ*0.01)16I64 master_sleep_jiffy;17CTask *animate_tasks[mp_cnt];18 19#define LENS_COLOR      WHITE20#define MIRROR_COLOR    DKGRAY21CDC *map;22 23I64 photon_cnt,mirror_cnt,snell_cnt,normal_inhibit,zero_normal;24Bool full_speed,show_normals;25 26U8      *bmp_refract,*bmp_reflect;27F64     bmp_scale,find_normal_dist_sqr;28I64     bmp_mem,bmp_width,bmp_height,bmp_norm_radius;29 30#define BORDER  1031I64 BmpPeek(U8 *bmp,I64 x,I64 y)32{33  return Bt(bmp,y*bmp_width+x);34}35 36U0 BmpPlot(U8 *bmp,I64 x,I64 y,I64)37{38  if (0<=x<bmp_width && 0<=y<bmp_height)39    Bts(bmp,y*bmp_width+x);40}41 42U0 BmpLine(U8 *bmp,F64 x1,F64 y1,F64 x2,F64 y2)43{44  Line(bmp,x1*bmp_scale,y1*bmp_scale,0,x2*bmp_scale,y2*bmp_scale,0,&BmpPlot);45}46 47Photon *PhotonNew()48{49  I64 num=photon_cnt++%mp_cnt;50  Photon *res=CAlloc(sizeof(Photon));51  while (LBts(&p_root_locks,num))52    Yield;53  QueIns(res,p_root[num].last);54  LBtr(&p_root_locks,num);55  return res;56}57 58#define VECTOR 2059U0 DrawIt(CTask *,CDC *dc)60{61  I64 i;62  Photon *tmpp;63  GrBlot(dc,0,0,map);64  dc->color=WHITE;65  GrPrint(dc,0,0,"Mem:0x%X %,dMeg Scale:%0.3f (%d,%d)-->(%d,%d)",66        bmp_mem,bmp_mem/1024/1024,bmp_scale,67        map->width,map->height,bmp_width,bmp_height);68  GrPrint(dc,0,FONT_HEIGHT,69        "PhotonCnt:%d MirrorCnt:%d SnellCnt:%d SnellInhibit:%d ZeroNormal:%d",70        photon_cnt,mirror_cnt,snell_cnt,normal_inhibit,zero_normal);71  for (i=0;i<mp_cnt;i++) {72    while (LBts(&p_root_locks,i))73      Yield;74    tmpp=p_root[i].next;75    while (tmpp!=&p_root[i]) {76      dc->color=LTRED;77      GrLine(dc,tmpp->p.x-VECTOR*tmpp->v.x,tmpp->p.y-VECTOR*tmpp->v.y,78            tmpp->p.x,tmpp->p.y);79      if (show_normals) {80        dc->color=LTGREEN;81        GrLine(dc,tmpp->p.x,tmpp->p.y,82              tmpp->p.x+VECTOR*tmpp->n.x,tmpp->p.y+VECTOR*tmpp->n.y);83      }84      tmpp=tmpp->next;85    }86    LBtr(&p_root_locks,i);87  }88}89 90#define WING    991 92U0 RayBurst(I64 x1,I64 y1,I64 x2,I64 y2)93{94  CD3 p,v,n,n2;95  I64 i;96  Photon *tmpp;97  if ((x1!=x2 || y1!=y2) && BORDER+WING<x2<map->width-BORDER-WING &&98        BORDER+WING<y2<map->height-BORDER-WING) {99    D3Equ(&p,x2,y2);100    D3Equ(&v,x2-x1,y2-y1);101    D3Unit(&v);102    D3Equ(&n,v.y,-v.x);103 104    tmpp=PhotonNew;105    D3Copy(&tmpp->p,&p);106    D3Copy(&tmpp->v,&v);107 108    for (i=2;i<=WING;i+=3) {109      D3Mul(&n2,i,&n);110 111      tmpp=PhotonNew;112      D3Add(&tmpp->p,&p,&n2);113      D3Copy(&tmpp->v,&v);114 115      tmpp=PhotonNew;116      D3Sub(&tmpp->p,&p,&n2);117      D3Copy(&tmpp->v,&v);118    }119  }120}121 122U0 RandomBurst()123{124  I64 i;125  F64 theta;126  Photon *tmpp;127  for (i=0;i<256;i++) {128    tmpp=PhotonNew;129    D3Equ(&tmpp->p,(Fs->pix_width-BORDER*2)*Rand+BORDER,130                (Fs->pix_height-BORDER*2)*Rand+BORDER);131    theta=2*pi*Rand;132    D3Equ(&tmpp->v,Cos(theta),Sin(theta));133  }134}135 136U0 FindNormal(U8 *bmp,Photon *tmpp)137{138  CD3 p,p1,p2;139  F64 step,x,y,theta=Arg(tmpp->v.x,tmpp->v.y),phi;140  I64 state;141 142  D3Copy(&tmpp->p_normal_inhibit,&tmpp->p);143 144  //Coarse grains has black and white filled-in BSplines.145  //Fine grained has only white outline without being filled-in.146 147  //Back-up a step and move fwd to get a fined-grained value148  //for the point of contact.149  D3SubEqu(&tmpp->p,&tmpp->v);150  D3Mul(&p,bmp_scale,&tmpp->p);151  D3Copy(&p1,&p);152  while (BmpPeek(bmp,p1.x,p1.y)==BLACK &&153        D3DistSqr(&p,&p1)<find_normal_dist_sqr)154    D3AddEqu(&p1,&tmpp->v);155  D3Copy(&p,&p1);156  D3Div(&tmpp->p,&p,bmp_scale);157 158  //Draw an arc one direction, finding point of contact.159  for (step=1.0;step>=0.01;step/=4) {160    for (phi=0;phi<=pi/4;phi+=step*pi/bmp_norm_radius) {161      x=p.x+bmp_norm_radius*Cos(theta+pi-pi/4-phi);162      y=p.y+bmp_norm_radius*Sin(theta+pi-pi/4-phi);163      if (state=BmpPeek(bmp,x,y))164        goto fn_p1;165      x=p.x+bmp_norm_radius*Cos(theta+pi-pi/4+phi);166      y=p.y+bmp_norm_radius*Sin(theta+pi-pi/4+phi);167      if (state=BmpPeek(bmp,x,y))168        goto fn_p1;169    }170    for (;phi<=3*pi/4;phi+=step*pi/bmp_norm_radius) {171      x=p.x+bmp_norm_radius*Cos(theta+pi-pi/4-phi);172      y=p.y+bmp_norm_radius*Sin(theta+pi-pi/4-phi);173      if (state=BmpPeek(bmp,x,y))174        goto fn_p1;175    }176  }177fn_p1:178  if (state)179    D3Equ(&p1,x,y);180  else181    D3Copy(&p1,&tmpp->p);182 183    //Draw an arc other direction, finding point of contact.184  for (step=1.0;step>=0.01;step/=4) {185    for (phi=0;phi<=pi/4;phi+=step*pi/bmp_norm_radius) {186      x=p.x+bmp_norm_radius*Cos(theta+pi+pi/4+phi);187      y=p.y+bmp_norm_radius*Sin(theta+pi+pi/4+phi);188      if (state=BmpPeek(bmp,x,y))189        goto fn_p2;190      x=p.x+bmp_norm_radius*Cos(theta+pi+pi/4-phi);191      y=p.y+bmp_norm_radius*Sin(theta+pi+pi/4-phi);192      if (state=BmpPeek(bmp,x,y))193        goto fn_p2;194    }195    for (;phi<=3*pi/4;phi+=step*pi/bmp_norm_radius) {196      x=p.x+bmp_norm_radius*Cos(theta+pi+pi/4+phi);197      y=p.y+bmp_norm_radius*Sin(theta+pi+pi/4+phi);198      if (state=BmpPeek(bmp,x,y))199        goto fn_p2;200    }201  }202fn_p2:203  if (state)204    D3Equ(&p2,x,y);205  else206    D3Copy(&p2,&tmpp->p);207 208  D3Sub(&p,&p1,&p2);209  if (D3NormSqr(&p)<0.01) {210    D3Equ(&tmpp->n,Cos(theta),Sin(theta));211    lock {zero_normal++;}212  } else {213    D3Equ(&tmpp->n,p.y,-p.x);214    if (D3Dot(&tmpp->n,&tmpp->v)<0)215      D3Equ(&tmpp->n,-p.y,p.x);216    D3Unit(&tmpp->n);217  }218}219 220U0 Mirror(Photon *tmpp)221{/*<1>/* Graphics Not Rendered in HTML */222 223 224 225 226 227 228 229 230 231 232thetaout = pi+thetan -  (thetain-thetan)233 234*/235  F64 theta=Arg(tmpp->v.x,tmpp->v.y),thetan;236  FindNormal(bmp_reflect,tmpp);237  thetan=Arg(tmpp->n.x,tmpp->n.y);238 239  D3Equ(&tmpp->v,Cos(2*thetan+pi-theta),Sin(2*thetan+pi-theta));240  lock {mirror_cnt++;}241}242 243U0 SnellsLaw(Photon *tmpp,I64 last,I64 next)244{245//n1 and n2 are refraction index.246//n1 Sin(theta1) == n2 Sin(theta2)247  F64 theta=Arg(tmpp->v.x,tmpp->v.y),thetan,n1,n2,theta1,theta2;248  if (last==LENS_COLOR)249    n1=1.5;250  else251    n1=1.0;252  if (next==LENS_COLOR)253    n2=1.5;254  else255    n2=1.0;256  FindNormal(bmp_refract,tmpp);257  thetan=Arg(tmpp->n.x,tmpp->n.y);258 259  //Dot=m1m2Cos(theta);260  theta1=ACos(D3Dot(&tmpp->n,&tmpp->v));261  theta2=ASin(n1*Sin(theta1)/n2);262  if (Wrap(theta-thetan)>=0)263    theta=thetan+theta2;264  else265    theta=thetan-theta2;266 267  D3Equ(&tmpp->v,Cos(theta),Sin(theta));268  lock {snell_cnt++;}269}270 271U0 AnimateTask(I64)272{273  while (TRUE) {274    master_sleep_jiffy+=ANIMATE_JIFFIES;275    if (cnts.jiffies>=master_sleep_jiffy)276      master_sleep_jiffy=cnts.jiffies+ANIMATE_JIFFIES;277    SleepUntil(master_sleep_jiffy);278  }279}280 281#define BABY_STEPS      4282 283U0 MPAnimateTask(I64)284{285  I64   i,last_master_jiffy=0,286        timeout_jiffy=master_sleep_jiffy+ANIMATE_JIFFIES,287        last,next;288  Bool  inhibit;289  CD3   step;290  Photon *tmpp,*root=&p_root[Gs->num];291  while (TRUE) {292    while (LBts(&p_root_locks,Gs->num))293      Yield;294    tmpp=root->next;295    while (tmpp!=root) {296      for (i=0;i<BABY_STEPS;i++) {297        last=GrPeek(map,tmpp->p.x,tmpp->p.y);298        D3Div(&step,&tmpp->v,BABY_STEPS);299        D3AddEqu(&tmpp->p,&step);300        if (tmpp->p.x<BORDER) {301          tmpp->p.x=2*BORDER-tmpp->p.x;302          tmpp->v.x=-tmpp->v.x;303        }304        if (tmpp->p.x>=map->width-BORDER) {305          tmpp->p.x-=tmpp->p.x-map->width+BORDER;306          tmpp->v.x=-tmpp->v.x;307        }308        if (tmpp->p.y<BORDER) {309          tmpp->p.y=2*BORDER-tmpp->p.y;310          tmpp->v.y=-tmpp->v.y;311        }312        if (tmpp->p.y>=map->height-BORDER) {313          tmpp->p.y-=tmpp->p.y-map->height+BORDER;314          tmpp->v.y=-tmpp->v.y;315        }316        next=GrPeek(map,tmpp->p.x,tmpp->p.y);317 318        if (D3DistSqr(&tmpp->p_normal_inhibit,&tmpp->p)<4.0)319          inhibit=TRUE;320        else321          inhibit=FALSE;322 323        if (last!=next) {324          if ((last==BLACK && next==LENS_COLOR) ||325                (last==LENS_COLOR && next==BLACK)) {326            if (inhibit)327              lock {normal_inhibit++;}328            else329              SnellsLaw(tmpp,last,next);330          } else if (last==BLACK && next==MIRROR_COLOR) {331            if (inhibit)332              lock {normal_inhibit++;}333            else334              Mirror(tmpp);335          } else if (!inhibit)336            D3Zero(&tmpp->p_normal_inhibit);337        } else if (!inhibit)338          D3Zero(&tmpp->p_normal_inhibit);339      }340 341      tmpp=tmpp->next;342      if (cnts.jiffies>=timeout_jiffy)343        break;344    }345    LBtr(&p_root_locks,Gs->num);346    if (cnts.jiffies>=timeout_jiffy) {347      Sleep(1);348      timeout_jiffy=master_sleep_jiffy+ANIMATE_JIFFIES;349    }350    if (!full_speed) {351      while (master_sleep_jiffy==last_master_jiffy)352        Sleep(1);353      last_master_jiffy=master_sleep_jiffy;354      SleepUntil(master_sleep_jiffy);355      timeout_jiffy=master_sleep_jiffy+ANIMATE_JIFFIES;356    }357  }358}359 360U0 Init()361{362  I64 i;363  master_sleep_jiffy=cnts.jiffies;364  full_speed=show_normals=FALSE;365  photon_cnt=mirror_cnt=snell_cnt=normal_inhibit=zero_normal=0;366  map=DCNew(Fs->pix_width,Fs->pix_height);367  for (i=0;i<mp_cnt;i++) {368    while (LBts(&p_root_locks,i))369      Yield;370    QueInit(&p_root[i]);371    LBtr(&p_root_locks,i);372  }373//x*y=bmp_mem*8374  //x/y=640/480375  //x=640/480*y376  //640/480*y^2=bmp_mem*8377  //y=Sqrt(bmp_mem*8*480/640)378  //bmp_scale=Sqrt(bmp_mem*8*480/640)/480379  bmp_scale=Sqrt(bmp_mem/2*8*Fs->pix_height/Fs->pix_width)/Fs->pix_height;380 381  find_normal_dist_sqr=2*Sqr(bmp_scale);382#assert Sqrt(2)<=BORDER383 384  bmp_width =bmp_scale*Fs->pix_width;385  bmp_height=bmp_scale*Fs->pix_height;386  bmp_refract=CAlloc(bmp_width*bmp_height/8);387  bmp_reflect=CAlloc(bmp_width*bmp_height/8);388  bmp_norm_radius=Min(10*bmp_scale,250);389#assert 10<=BORDER390}391 392U0 CleanUp()393{394  I64 i;395  for (i=0;i<mp_cnt;i++) {396    while (LBts(&p_root_locks,i))397      Yield;398    QueDel(&p_root[i],TRUE);399    LBtr(&p_root_locks,i);400  }401  DCDel(map);402  Free(bmp_refract);403  Free(bmp_reflect);404}405 406#define LTM_REFLECT_LINE        0407#define LTM_REFLECT_SPLINE      1408#define LTM_REFRACT_LINE        2409#define LTM_REFRACT_SPLINE      3410#define LTM_REFRACT_FLOOD_FILL  4411#define LTM_TEST_RAY            5412 413U0 LTMenuSet(I64 mode)414{415  CMenuEntry *entry=MenuEntryFind(Fs->cur_menu,"View/ToggleNormals");416  if (show_normals)417    entry->checked=TRUE;418  else419    entry->checked=FALSE;420 421  entry=MenuEntryFind(Fs->cur_menu,"Mode/ReflectLine");422  if (mode==LTM_REFLECT_LINE)423    entry->checked=TRUE;424  else425    entry->checked=FALSE;426  entry=MenuEntryFind(Fs->cur_menu,"Mode/ReflectSpline");427  if (mode==LTM_REFLECT_SPLINE)428    entry->checked=TRUE;429  else430    entry->checked=FALSE;431  entry=MenuEntryFind(Fs->cur_menu,"Mode/RefractLine");432  if (mode==LTM_REFRACT_LINE)433    entry->checked=TRUE;434  else435    entry->checked=FALSE;436  entry=MenuEntryFind(Fs->cur_menu,"Mode/RefractSpline");437  if (mode==LTM_REFRACT_SPLINE)438    entry->checked=TRUE;439  else440    entry->checked=FALSE;441  entry=MenuEntryFind(Fs->cur_menu,"Mode/RefractFloodFill");442  if (mode==LTM_REFRACT_FLOOD_FILL)443    entry->checked=TRUE;444  else445    entry->checked=FALSE;446  entry=MenuEntryFind(Fs->cur_menu,"Mode/TestRay");447  if (mode==LTM_TEST_RAY)448    entry->checked=TRUE;449  else450    entry->checked=FALSE;451}452 453#define PTS_NUM 1024454U0 LightTable()455{456  I64 msg_code,mode=LTM_REFLECT_LINE,i,cnt,arg1,arg2,x1,y1,x2,y2;457  CD3I32 *c=MAlloc(PTS_NUM*sizeof(CD3I32));458 459  p_root_locks=0;460  MenuPush(461        "File {"462        "  Restart(,'\n');"463        "  Abort(,CH_SHIFT_ESC);"464        "  Exit(,CH_ESC);"465        "}"466        "Mode {"467        "  ReflectLine(,'0');"468        "  ReflectSpline(,'1');"469        "  RefractLine(,'2');"470        "  RefractSpline(,'3');"471        "  RefractFloodFill(,'4');"472        "  TestRay(,'5');"473        "}"474        "Play {"475        "  RandomBurst(,'r');"476        "  ElapseTime(,'e');"477        "}"478        "View {"479        "  ToggleNormals(,'n');"480        "}"481        );482  LTMenuSet(mode);483 484  MemBIOSRep;485  bmp_mem=GetI64("\n\n\nHow much memory for the high resolution\n"486        "shadow bitmap that helps improve the\n"487        "accuracy of the normal vector estimate?\n"488        "You can choose up to the largest\n"489        "contiguous chunk of physical memory.\n\n"490        "Mem (0x%0X):",1024*1024*16);491 492  SettingsPush; //See SettingsPush493  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-494        WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU;495  Fs->text_attr=BLACK<<4+WHITE; //Current CTask is Fs segment register.496  AutoComplete;497  WinBorder;498  WinMax;499  DocCursor;500  DocClear;501  Init;502  Fs->draw_it=&DrawIt;503  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);504  for (i=0;i<mp_cnt;i++)505    animate_tasks[i]=Spawn(&MPAnimateTask,NULL,"MPAnimate",i);506  try {507    while (TRUE) {508      msg_code=GetMsg(&arg1,&arg2,509            1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_L_UP+1<<MSG_MS_R_UP);510lt_restart:511      switch (msg_code) {512        case MSG_MS_L_UP:513          Sweep(100,90,100);514          x2=arg1; y2=arg2;515          switch (mode) {516            case LTM_REFRACT_FLOOD_FILL:517              map->color=LENS_COLOR;518              GrFloodFill(map,x2,y2);519              mode=LTM_REFLECT_LINE;520              LTMenuSet(mode);521              break;522            case LTM_TEST_RAY:523              RayBurst(x1,y1,x2,y2);524              break;525          }526          break;527        case MSG_MS_L_DOWN:528          x1=arg1; y1=arg2;529          switch (mode) {530            case LTM_REFLECT_LINE:531            case LTM_REFRACT_LINE:532              if (mode==LTM_REFLECT_LINE)533                map->color=ROP_XOR+MIRROR_COLOR;534              else535                map->color=ROP_XOR+LENS_COLOR;536              while (TRUE) {537                x2=arg1; y2=arg2;538                GrLine(map,x1,y1,x2,y2);539                msg_code=GetMsg(&arg1,&arg2,540                      1<<MSG_KEY_DOWN+1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);541                GrLine(map,x1,y1,x2,y2);542                if (msg_code==MSG_KEY_DOWN)543                  goto lt_restart;544                else if (msg_code==MSG_MS_L_UP) {545                  Sweep(100,90,100);546                  x2=arg1; y2=arg2;547                  break;548                }549              }550              if (mode==LTM_REFLECT_LINE)551                map->color=MIRROR_COLOR;552              else553                map->color=LENS_COLOR;554              GrLine(map,x1,y1,x2,y2);555              if (mode==LTM_REFLECT_LINE)556                BmpLine(bmp_reflect,x1,y1,x2,y2);557              else558                BmpLine(bmp_refract,x1,y1,x2,y2);559              break;560            case LTM_REFLECT_SPLINE:561            case LTM_REFRACT_SPLINE:562              cnt=0;563              if (mode==LTM_REFLECT_SPLINE)564                map->color=ROP_XOR+MIRROR_COLOR;565              else566                map->color=ROP_XOR+LENS_COLOR;567              do {568                c[cnt].x=arg1; c[cnt].y=arg2; c[cnt].z=0;569                Gr2BSpline(map,c,cnt+1);570                msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_UP+571                      1<<MSG_MS_MOVE+1<<MSG_MS_R_UP);572                Gr2BSpline(map,c,cnt+1);573                if (msg_code==MSG_KEY_DOWN)574                  goto lt_restart;575                else if (msg_code==MSG_MS_L_UP) {576                  Sweep(100,90,100);577                  cnt++;578                }579              } while (cnt<PTS_NUM-1 && msg_code!=MSG_MS_R_UP);580              if (mode==LTM_REFLECT_SPLINE)581                map->color=MIRROR_COLOR;582              else583                map->color=LENS_COLOR;584              Gr2BSpline3(map,c,cnt);585              for (i=0;i<cnt;i++) {586                c[i].x*=bmp_scale;587                c[i].y*=bmp_scale;588              }589              if (mode==LTM_REFLECT_SPLINE)590                BSpline2(bmp_reflect,c,cnt,&BmpPlot);591              else592                BSpline2(bmp_refract,c,cnt,&BmpPlot);593              mode=LTM_REFLECT_LINE;594              LTMenuSet(mode);595              break;596          }597          break;598        case MSG_MS_R_UP:599          i=PopUpPickLst("Reflect Line\0Reflect Spline\0Refract Line\0"600                "Refract Spline\0Refract Flood Fill\0TestRay\0");601          if (i>=0) {602            mode=i;603            LTMenuSet(mode);604          }605          break;606        case MSG_KEY_DOWN:607          switch (arg1) {608            case '\n':609              CleanUp;610              Init;611              mode=LTM_REFLECT_LINE;612              LTMenuSet(mode);613              break;614            case 'r':615              RandomBurst;616              break;617            case 'e':618              full_speed=TRUE;619              Sleep(1500);620              FlushMsgs;621              full_speed=FALSE;622              break;623            case 'n':624              show_normals=!show_normals;625              LTMenuSet(mode);626              break;627            case '0'...'5':628              mode=arg1-'0';629              LTMenuSet(mode);630              break;631            case CH_ESC:632            case CH_SHIFT_ESC:633              goto lt_done;634          }635          break;636      }637    }638lt_done:639    GetMsg(,,1<<MSG_KEY_UP);640  } catch641    PutExcept;642  Free(c);643  SettingsPop;644  for (i=0;i<mp_cnt;i++)645    Kill(animate_tasks[i]);646  CleanUp;647  MenuPop;648}649 650LightTable;651