hschumann2/TempleOS-Source-Code
0838
1 2F64 SpanTime()3{4 if (run_bttn.state)5 return a.elapsed_t+tS-a.start_wall_t;6 else7 return a.elapsed_t;8}9 10F64 Cost(CMathODE *ode)11{12 MyMass *tmpm;13 MySpring *tmps;14 F64 res=0;15 tmpm=ode->next_mass;16 while (tmpm!=&ode->next_mass) {17 res+=tmpm->cost;18 tmpm=tmpm->next;19 }20 tmps=ode->next_spring;21 while (tmps!=&ode->next_spring) {22 res+=tmps->cost;23 tmps=tmps->next;24 }25 return res;26}27 28U0 DrawIt(CTask *task,CDC *dc)29{30 MyMass *tmpm;31 MySpring *tmps;32 33 tmps=ode->next_spring;34 while (tmps!=&ode->next_spring) {35 if (!(tmps->flags&SSF_INACTIVE)) {36 dc->color=tmps->color;37 dc->thick=tmps->thick;38 GrLine3(dc,tmps->end1->x,tmps->end1->y,0,39 tmps->end2->x,tmps->end2->y,0);40 }41 tmps=tmps->next;42 }43 44 if (cursor_mass) {45 dc->color=RED;46 dc->thick=2;47 GrLine3(dc,ms.pos.x-task->pix_left-task->scroll_x,48 ms.pos.y-task->pix_top-task->scroll_y,0,49 cursor_mass->x,cursor_mass->y,0);50 }51 52 tmpm=ode->next_mass;53 while (tmpm!=&ode->next_mass) {54 if (!(tmpm->flags&MSF_INACTIVE)) {55 dc->color=BLACK;56 GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);57 GrFloodFill(dc,tmpm->x,tmpm->y,TRUE);58 dc->color=tmpm->color;59 GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);60 GrFloodFill(dc,tmpm->x,tmpm->y,TRUE);61 dc->color=BLACK;62 GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);63 }64 tmpm=tmpm->next;65 }66 67 dc->color=BLACK;68 GrPrint(dc,90,0,"Cost:%12.2,f",Cost(ode));69 GrPrint(dc,90,FONT_HEIGHT,"Time:%12.2f",SpanTime);70}71 72MyMass *PlaceMass(I64 x, I64 y)73{74 MyMass *tmpm=CAlloc(sizeof(MyMass));75 tmpm->drag_profile_factor=1.0;76 tmpm->x=x;77 tmpm->y=y;78 tmpm->mass=MASS_MASS;79 tmpm->radius=MASS_RADIUS;80 tmpm->cost=25.0*COST_SCALE;81 tmpm->color=YELLOW;82 QueIns(tmpm,ode->last_mass);83 return tmpm;84}85 86U0 NullSpring(MySpring *tmps,F64 scale)87{88 F64 d=D3Dist(&tmps->end1->x,&tmps->end2->x);89 tmps->rest_len=d*scale;90 tmps->compression_strength=91 tmps->base_compression_strength/(tmps->rest_len+1.0);92 tmps->tensile_strength=tmps->base_tensile_strength/(tmps->rest_len+1.0);93 tmps->const=tmps->base_const/(tmps->rest_len+1.0);94 tmps->cost=tmps->base_cost*tmps->rest_len;95}96 97U0 MoveMass(MyMass *tmpm,I64 x, I64 y)98{99 MySpring *tmps;100 tmpm->x=x;101 tmpm->y=y;102 tmpm->DxDt=0;103 tmpm->DyDt=0;104 tmps=ode->next_spring;105 while (tmps!=&ode->next_spring) {106 if (tmps->end1==tmpm || tmps->end2==tmpm) {107 if (tmps->flags&SSF_NO_COMPRESSION)108 NullSpring(tmps,WIRE_PERCENT);109 else110 NullSpring(tmps,1.0);111 }112 tmps=tmps->next;113 }114}115 116U0 DelSpring(MySpring *tmps)117{118 QueRem(tmps);119 Free(tmps);120}121 122U0 DelMass(MyMass *tmpm)123{124 MySpring *tmps,*tmps1;125 tmps=ode->next_spring;126 while (tmps!=&ode->next_spring) {127 tmps1=tmps->next;128 if (tmps->end1==tmpm || tmps->end2==tmpm)129 DelSpring(tmps);130 tmps=tmps1;131 }132 QueRem(tmpm);133 Free(tmpm);134}135 136U0 DrawSpring(CDC *dc,MyMass *tmpm,I64 x,I64 y)137{138 switch (mode_bttn.state) {139 case MD_CONCRETE:140 dc->color=LTGRAY;141 dc->thick=2;142 break;143 case MD_STEEL:144 dc->color=DKGRAY;145 dc->thick=2;146 break;147 case MD_WIRE:148 dc->color=RED;149 dc->thick=1;150 break;151 }152 GrLine3(dc,tmpm->x,tmpm->y,0,x,y,0);153}154 155U0 PlaceSpring(MyMass *tmpm1,MyMass *tmpm2)156{157 MySpring *tmps=CAlloc(sizeof(MySpring));158 tmps->end1=tmpm1;159 tmps->end2=tmpm2;160 switch (mode_bttn.state) {161 case MD_CONCRETE:162 tmps->base_const = 3.00*SPRING_SCALE;163 tmps->base_compression_strength=10.00*STRENGTH_SCALE;164 tmps->base_tensile_strength = 0.35*STRENGTH_SCALE;165 tmps->base_cost = 0.30*COST_SCALE;166 NullSpring(tmps,1.0);167 tmps->color=LTGRAY;168 tmps->thick=2;169 break;170 case MD_STEEL:171 tmps->base_const = 1.00*SPRING_SCALE;172 tmps->base_compression_strength= 1.00*STRENGTH_SCALE;173 tmps->base_tensile_strength = 1.00*STRENGTH_SCALE;174 tmps->base_cost = 1.00*COST_SCALE;175 NullSpring(tmps,1.0);176 tmps->color=DKGRAY;177 tmps->thick=2;178 break;179 case MD_WIRE:180 tmps->base_const = 0.25*SPRING_SCALE;181 tmps->base_compression_strength= 0.00;182 tmps->base_tensile_strength = 0.50*STRENGTH_SCALE;183 tmps->base_cost = 0.10*COST_SCALE;184 NullSpring(tmps,WIRE_PERCENT);185 tmps->color=RED;186 tmps->thick=1;187 tmps->flags|=SSF_NO_COMPRESSION;188 break;189 }190 QueIns(tmps,ode->last_spring);191}192 193U0 AnimateTask(SpanAnimateStruct *a)194{195 MySpring *tmps,*tmps1;196 Bool old_run=FALSE;197 F64 f;198 while (TRUE) {199 tmps=ode->next_spring;200 while (tmps!=&ode->next_spring) {201 tmps1=tmps->next;202 f=tmps->f;203 if (f>0 && f>tmps->compression_strength &&204 !(tmps->flags&SSF_NO_COMPRESSION)||205 f<0 && -f>tmps->tensile_strength &&206 !(tmps->flags&SSF_NO_TENSION))207 tmps->flags|=SSF_INACTIVE;208 tmps=tmps1;209 }210 AdjustLoads(ode);211 Refresh; //CMathODE updated once per refresh.212 if (old_run!=run_bttn.state) {213 if (run_bttn.state) {214 if (!a->elapsed_t || !a->saved_ode) {215 Free(a->saved_ode);216 a->saved_ode=SpanSave(ode);217 }218 a->start_wall_t=tS;219 ODEPause(ode,OFF);220 } else {221 ODEPause(ode);222 a->elapsed_t+=tS-a->start_wall_t;223 }224 old_run=run_bttn.state;225 }226 }227}228 229U0 Init(SpanAnimateStruct *a)230{231 SpanDel(ode);232 ode=SpanNew;233 234 run_bttn.state=0;235 Refresh(2); //Allow stop to reg in animate task.236 237 if (a->saved_ode)238 SpanLoad(ode,a->saved_ode);239 else240 SpanBridge1Init(ode);241 a->elapsed_t=0;242 cursor_mass=NULL;243}244 245U0 SongTask(I64)246{//Song by Terry A. Davis247 Fs->task_end_cb=&SndTaskEndCB;248 MusicSettingsRst;249 music.tempo= 3.636;250 music.stacatto_factor= 0.902;251 while (TRUE) {252 Play("5q.EeDqED4G5DhE");253 Play("5q.EeDqED4G5DhE");254 Play("5q.FeEFEqF4G5EhF");255 Play("5q.FeEFEqF4G5EhF");256 }257}258 259U0 Span()260{261 I64 msg_code,arg1,arg2;262 MyMass *tmpm1=NULL,*tmpm2=NULL;263 MySpring *tmps;264 CCtrl *bt_run,*bt_mode;265 U8 *src;266 CDC *dc=DCAlias;267 268 SettingsPush; //See SettingsPush269 Fs->text_attr=BROWN<<4+BLACK;270 AutoComplete;271 WinBorder;272 WinMax;273 DocCursor;274 Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);275 276 bt_run =CtrlBttnNew(0,0, 80,,277 2,"Stopped\0Running\0",run_colors,&run_bttn);278 bt_mode=CtrlBttnNew(0,3.0*FONT_HEIGHT,80,,279 MD_MODES_NUM,Define("ST_SPAN_MODES"),mode_colors,&mode_bttn);280 a.saved_ode=NULL;281 282 Fs->win_inhibit|=WIG_DBL_CLICK;283 284 MenuPush(285 "File {"286 " New(,CH_CTRLN);"287 " Open(,CH_CTRLO);"288 " SaveAs(,CH_CTRLA);"289 " Abort(,CH_SHIFT_ESC);"290 " Exit(,CH_ESC);"291 "}"292 "Play {"293 " Restart(,'\n');"294 " RunStop(,CH_SPACE);"295 " Mass(,'m');"296 " Concrete(,'c');"297 " Steel(,'s');"298 " Wire(,'w');"299 " Move(,'v');"300 " Delete(,'d');"301 "}"302 );303 304 ode=NULL;305 Init(&a);306 Fs->animate_task=Spawn(&AnimateTask,&a,"Animate",,Fs);307 Fs->draw_it=&DrawIt;308 309 PopUpOk(310 "Build a bridge to hold-up the\n"311 "red masses. Test your design\n"312 "by pressing run/stop.\n\n"313 "The lowest cost bridge that\n"314 "stays standing wins.\n\n"315 "For a variation, try without\n"316 "using the center base point.\n"317 "\n"318 "Use\n"319 "\t$GREEN$'m'$FG$ass\n"320 "\t$GREEN$'c'$FG$oncrete\n"321 "\t$GREEN$'s'$FG$teel\n"322 "\t$GREEN$'w'$FG$ire\n"323 "\nto sel materials.\n");324 325 try {326 while (TRUE) {327 msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|328 1<<MSG_MS_L_UP|1<<MSG_KEY_DOWN|1<<MSG_MS_MOVE);329 DCFill(dc);330 switch (msg_code) {331 case MSG_MS_L_DOWN:332 cursor_mass=tmpm1=tmpm2=NULL;333 switch (mode_bttn.state) {334 case MD_MASS:335 PlaceMass(arg1,arg2);336 break;337 case MD_CONCRETE:338 case MD_STEEL:339 case MD_WIRE:340 tmpm1=MassFind(ode,arg1,arg2);341 break;342 case MD_MOVE:343 if (run_bttn.state)344 cursor_mass=MassFind(ode,arg1,arg2);345 else346 if (tmpm1=MassFind(ode,arg1,arg2))347 MoveMass(tmpm1,arg1,arg2);348 break;349 case MD_DELETE:350 MassOrSpringFind(ode,&tmpm1,&tmps,arg1,arg2);351 if (tmpm1)352 DelMass(tmpm1);353 if (tmps)354 DelSpring(tmps);355 break;356 }357 break;358 case MSG_MS_L_UP:359 switch (mode_bttn.state) {360 case MD_CONCRETE:361 case MD_STEEL:362 case MD_WIRE:363 if (tmpm1 && (tmpm2=MassFind(ode,arg1,arg2)) && tmpm1!=tmpm2)364 PlaceSpring(tmpm1,tmpm2);365 break;366 case MD_MOVE:367 if (!run_bttn.state && tmpm1)368 MoveMass(tmpm1,arg1,arg2);369 break;370 }371 cursor_mass=tmpm1=tmpm2=NULL;372 break;373 case MSG_MS_MOVE:374 switch (mode_bttn.state) {375 case MD_MOVE:376 if (!run_bttn.state && tmpm1)377 MoveMass(tmpm1,arg1,arg2);378 break;379 case MD_CONCRETE:380 case MD_STEEL:381 case MD_WIRE:382 if (tmpm1) {383 DrawSpring(dc,tmpm1,arg1,arg2);384 }385 break;386 }387 break;388 case MSG_MS_R_DOWN:389 mode_bttn.state++;390 if (mode_bttn.state>=MD_MODES_NUM)391 mode_bttn.state=0;392 cursor_mass=tmpm1=tmpm2=NULL;393 break;394 case MSG_KEY_DOWN:395 switch (arg1) {396 case '\n':397 if (!SpanTime || !a.saved_ode) {398 Free(a.saved_ode);399 a.saved_ode=SpanSave(ode);400 }401 Init(&a);402 break;403 case CH_CTRLN:404 Free(a.saved_ode);405 a.saved_ode=NULL;406 Init(&a);407 break;408 case CH_CTRLO:409 if (src=SpanRead) {410 Free(a.saved_ode);411 a.saved_ode=src;412 Init(&a);413 }414 break;415 case CH_CTRLA:416 if (!SpanTime || !a.saved_ode) {417 Free(a.saved_ode);418 a.saved_ode=SpanSave(ode);419 }420 Init(&a);421 SpanWrite(ode);422 break;423 case CH_SPACE:424 run_bttn.state=!run_bttn.state;425 break;426 case 'c':427 mode_bttn.state=MD_CONCRETE;428 break;429 case 's':430 mode_bttn.state=MD_STEEL;431 break;432 case 'w':433 mode_bttn.state=MD_WIRE;434 break;435 case 'm':436 mode_bttn.state=MD_MASS;437 break;438 case 'v':439 mode_bttn.state=MD_MOVE;440 break;441 case 'd':442 mode_bttn.state=MD_DELETE;443 break;444 case CH_ESC:445 if (!SpanTime || !a.saved_ode) {446 Free(a.saved_ode);447 a.saved_ode=SpanSave(ode);448 }449 Init(&a);450 SpanWrite(ode);451 case CH_SHIFT_ESC:452 goto span_done;453 }454 break;455 }456 }457span_done: //Don't goto out of try458 GetMsg(,,1<<MSG_KEY_UP);459 } catch460 PutExcept;461 DocClear;462 SettingsPop;463 CtrlBttnDel(bt_run);464 CtrlBttnDel(bt_mode);465 SpanDel(ode);466 DCFill(dc);467 DCDel(dc);468 MenuPop;469}470 