Files
2017-01-22 20:26:44 +01:00

129 lines
2.9 KiB
HolyC

//Practice tracing circles
//Giotto, a famous artist, drew a freehand circle to get a job.
RegDft("TempleOS/CircleTrace","F64 best_score=999;\n");
RegExe("TempleOS/CircleTrace");
I64 cx,cy;
F64 avg_error=0,elapsed_time=0,total_error=0,score=999;
U0 SongTask(I64)
{
Fs->task_end_cb=&SndTaskEndCB;
MusicSettingsRst;
while (TRUE)
Play("5hEDC4A5RCDECR");
}
U0 DrawIt(CTask *task,CDC *dc)
{
GrPrint(dc,0,0,"Error:%6.3f Time:%6.3f Score:%6.3f Best:%8.3f",
avg_error,elapsed_time,score,best_score);
}
#define CIRCLE_RADIUS 100
#define CIRCUMFERENCE (2*ã*CIRCLE_RADIUS)
Bool CTPlot(CDC *dc,I64 x,I64 y,I64)
{
F64 rad=Sqrt(Sqr(x-cx)+Sqr(y-cy));
GrPlot(dc,x,y);
total_error+=Abs(rad-CIRCLE_RADIUS);
return TRUE;
}
U0 CircleTrace()
{
I64 msg_code,arg1,arg2,x1,y1;
F64 rad,t0,total_distance;
CDC *dc=DCAlias;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
AutoComplete;
WinBorder;
WinMax;
DocCursor;
DocClear;
cx=Fs->pix_width/2;
cy=Fs->pix_height/2;
Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
Fs->draw_it=&DrawIt;
DCFill;
dc->color=ROP_XOR+BLACK^TRANSPARENT;
GrCircle(dc,cx,cy,CIRCLE_RADIUS);
do {
msg_code=GetMsg(&arg1,&arg2,
1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN);
switch (msg_code) {
case MSG_KEY_UP:
break;
case MSG_MS_L_DOWN:
DCFill;
dc->color=ROP_XOR+BLACK^TRANSPARENT;
GrCircle(dc,cx,cy,CIRCLE_RADIUS);
dc->color=ROP_XOR+RED^TRANSPARENT;
t0=tS;
total_distance=0.001;
total_error=0;
x1=arg1; y1=arg2;
do {
msg_code=ScanMsg(&arg1,&arg2,
1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
switch (msg_code) {
case MSG_MS_L_UP:
break;
case MSG_MS_MOVE:
if (x1!=arg1 || y1!=arg2) {
total_distance+=Sqrt(Sqr(x1-arg1)+Sqr(y1-arg2));
Line(dc,x1,y1,0,arg1,arg2,0,&CTPlot);
x1=arg1;y1=arg2;
//undo overlapping pixs on segments
GrPlot(dc,x1,y1);
rad=Sqrt(Sqr(x1-cx)+Sqr(y1-cy));
total_error-=Abs(rad-CIRCLE_RADIUS);
}
break;
}
elapsed_time=tS-t0;
avg_error=total_error/total_distance;
score=elapsed_time*avg_error;
//$LK,"Sleep",A="MN:Sleep"$()s until the next time the
//window mgr task runs. The
//window mgr calls the UpdateWin() routine
//and places msgs in the que, so there's
//no need to do anything until the window mgr runs.
Refresh;
} while (msg_code!=MSG_MS_L_UP);
music.mute=TRUE; Sleep(200);
if (total_distance>0.95*CIRCUMFERENCE) {
if (score<best_score) {
Snd(86);Sleep(50);Snd;Sleep(50);
Snd(86);Sleep(50);Snd;Sleep(50);
Snd(86);Sleep(50);
best_score=score;
} else {
Snd(62);Sleep(50);
}
} else {
Snd(34);Sleep(1000);
}
Snd; Sleep(200); music.mute=FALSE;
break;
}
} while (msg_code!=MSG_KEY_DOWN || arg1!=CH_SHIFT_ESC && arg1!=CH_ESC);
GetMsg(,,1<<MSG_KEY_UP);
SettingsPop;
DCFill;
DCDel(dc);
RegWrite("TempleOS/CircleTrace","F64 best_score=%5.4f;\n",best_score);
}
CircleTrace; //Execute when #included