hschumann2/TempleOS-Source-Code
0847
1 2//This is a whimsical program which demonstrates some techniques.3 4#define BORDER 205 6#define PTY_PT 07#define PTY_CIRCLE 18#define PTY_LINE 29#define PTY_SPRITE 310#define PTY_NUM 411 12extern class PObj;13 14class PPt15{16 CD3I32 p;17};18 19class PCircle20{21 PObj *p;22 I64 radius;23};24 25class PLine26{27 PObj *p1,*p2;28};29 30class PCSprite31{32 PObj *p;33 U8 *img;34 I64 *r,35 *dr; //Rounding error might eventually screw this up36}37 38class PObj39{40 PObj *next,*last;41 I64 type,color;42 union {43 PPt p;44 PCircle c;45 PLine l;46 PCSprite g;47 };48};49 50class PickFrame51{52 PObj o_head;53 I64 o_cnts[PTY_NUM];54 I64 cx,cy;55};56 57#define IMGS_NUM 358 59 60 61 <1>/* Graphics Not Rendered in HTML */62 63 64 65 <2>/* Graphics Not Rendered in HTML */66 67 68 69 70 <3>/* Graphics Not Rendered in HTML */71 72 73U8 *imgs[IMGS_NUM]={<1>,<2>,<3>};74 75U0 DrawIt(CTask *task,CDC *dc)76{77 I64 *r,*old_r;78 PickFrame *pf=FramePtr("PickFrame",task);79 PObj *tmpo=pf->o_head.next;80 81 pf->cx=task->pix_width>>1;82 pf->cy=task->pix_height>>1;83 84 DCDepthBufAlloc(dc);85 86 dc->color=LTRED;87 dc->thick=3;88 GrBorder(dc,BORDER,BORDER,2*pf->cx-BORDER,2*pf->cy-BORDER);89 90 while (tmpo!=&pf->o_head) {91 dc->color=tmpo->color;92 switch (tmpo->type) {93 case PTY_PT:94 GrLine(dc,pf->cx+tmpo->p.p.x+2,pf->cy+tmpo->p.p.y+2,95 pf->cx+tmpo->p.p.x-2,pf->cy+tmpo->p.p.y-2);96 GrLine(dc,pf->cx+tmpo->p.p.x-2,pf->cy+tmpo->p.p.y+2,97 pf->cx+tmpo->p.p.x+2,pf->cy+tmpo->p.p.y-2);98 break;99 case PTY_CIRCLE:100 GrCircle(dc,pf->cx+tmpo->c.p->p.p.x,pf->cy+tmpo->c.p->p.p.y,101 tmpo->c.radius);102 break;103 case PTY_LINE:104 GrLine(dc,pf->cx+tmpo->l.p1->p.p.x,pf->cy+tmpo->l.p1->p.p.y,105 pf->cx+tmpo->l.p2->p.p.x,pf->cy+tmpo->l.p2->p.p.y);106 break;107 case PTY_SPRITE:108 old_r=dc->r;109 dc->r=tmpo->g.r;110 dc->x=pf->cx+tmpo->g.p->p.p.x;111 dc->y=pf->cy+tmpo->g.p->p.p.y;112 dc->z=GR_Z_ALL;113 dc->flags|=DCF_TRANSFORMATION;114 Sprite3(dc,0,0,0,tmpo->g.img);115 dc->flags&=~DCF_TRANSFORMATION;116 dc->r=old_r;117 118 //Updated each refresh, not guarenteed to be uniform.119 //Rounding error might corrupt, as well.120 r=Mat4x4MulMat4x4New(tmpo->g.dr,tmpo->g.r,task);121 Free(tmpo->g.r);122 tmpo->g.r=r;123 124 break;125 }126 tmpo=tmpo->next;127 }128}129 130PObj *PObjNew(PickFrame *pf,I64 type,I64 color)131{132 PObj *tmpo=CAlloc(sizeof(PObj));133 tmpo->type=type;134 tmpo->color=color;135 pf->o_cnts[type]++;136 QueIns(tmpo,pf->o_head.last);137 return tmpo;138}139 140U0 PObjDel(PickFrame *pf,PObj *tmpo)141{142 QueRem(tmpo);143 switch (tmpo->type) {144 case PTY_SPRITE:145 Free(tmpo->g.r);146 Free(tmpo->g.dr);147 break;148 }149 pf->o_cnts[tmpo->type]--;150 Free(tmpo);151}152 153PObj *PPtNew(PickFrame *pf,I64 x,I64 y)154{155 PObj *tmpo=PObjNew(pf,PTY_PT,BLACK);156 tmpo->p.p.x=x;157 tmpo->p.p.y=y;158 return tmpo;159}160 161PObj *PPtNum(PickFrame *pf,I64 num)162{163 PObj *tmpo=pf->o_head.next;164 while (tmpo!=&pf->o_head) {165 if (tmpo->type==PTY_PT && !num--)166 return tmpo;167 tmpo=tmpo->next;168 }169 return NULL;170}171 172PObj *PPtFind(PickFrame *pf,I64 x,I64 y)173{174 I64 dd,best_dd=I64_MAX;175 PObj *tmpo=pf->o_head.next,*res=NULL;176 while (tmpo!=&pf->o_head) {177 if (tmpo->type==PTY_PT) {178 dd=SqrI64(tmpo->p.p.x-x)+SqrI64(tmpo->p.p.y-y);179 if (dd<best_dd) {180 best_dd=dd;181 res=tmpo;182 }183 }184 tmpo=tmpo->next;185 }186 return res;187}188 189PObj *PCircleNew(PickFrame *pf,I64 p_num,I64 r)190{191 PObj *tmpo=PObjNew(pf,PTY_CIRCLE,RED);192 tmpo->c.p=PPtNum(pf,p_num);193 tmpo->c.radius=r;194 return tmpo;195}196 197PObj *PLineNew(PickFrame *pf,I64 p1_num,I64 p2_num)198{199 PObj *tmpo=PObjNew(pf,PTY_LINE,GREEN);200 tmpo->l.p1=PPtNum(pf,p1_num);201 tmpo->l.p2=PPtNum(pf,p2_num);202 return tmpo;203}204 205PObj *PCSpriteNew(PickFrame *pf,U8 *img,I64 p_num,I64 *r,I64 *dr)206{207 PObj *tmpo=PObjNew(pf,PTY_SPRITE,BLACK);208 tmpo->g.p=PPtNum(pf,p_num);209 tmpo->g.img=img;210 tmpo->g.r=r;211 tmpo->g.dr=dr;212 return tmpo;213}214 215PickFrame *Init()216{217 PickFrame *pf=CAlloc(sizeof(PickFrame));218 I64 i,*r,*dr;219 220 pf->cx=Fs->pix_width>>1;221 pf->cy=Fs->pix_height>>1;222 223 pf->o_head.next=pf->o_head.last=&pf->o_head;224 for (i=0;i<50;i++)225 PPtNew(pf,RandI32%(pf->cx-BORDER),RandI32%(pf->cy-BORDER));226 for (i=0;i<20;i++)227 PCircleNew(pf,pf->o_cnts[PTY_PT]*RandU16/U16_MAX,6);228 for (i=0;i<20;i++)229 PLineNew(pf,pf->o_cnts[PTY_PT]*RandU16/U16_MAX,230 pf->o_cnts[PTY_PT]*RandU16/U16_MAX);231 for (i=0;i<10;i++) {232 r=Mat4x4IdentNew;233 dr=Mat4x4IdentNew;234 Mat4x4RotZ(dr,0.05*2*(Rand-0.5));235 Mat4x4RotY(dr,0.05*2*(Rand-0.5));236 Mat4x4RotX(dr,0.05*2*(Rand-0.5));237 PCSpriteNew(pf,imgs[IMGS_NUM*RandU16/U16_MAX],238 pf->o_cnts[PTY_PT]*RandU16/U16_MAX,r,dr);239 }240 FramePtrSet("PickFrame",pf);241 return pf;242}243 244U0 CleanUp(PickFrame *pf)245{246 PObj *tmpo=pf->o_head.next,*tmpo1;247 while (tmpo!=&pf->o_head) {248 tmpo1=tmpo->next;249 PObjDel(pf,tmpo);250 tmpo=tmpo1;251 }252 Free(pf);253}254 255U0 Pick3D()256{257 I64 msg_code,arg1,arg2;258 PObj *tmpo;259 PickFrame *pf=NULL;260 261 FramePtrAdd("PickFrame");262 263 MenuPush(264 "File {"265 " Abort(,CH_SHIFT_ESC);"266 " Exit(,CH_ESC);"267 "}"268 "Play {"269 " Restart(,'\n');"270 "}"271 );272 SettingsPush; //See SettingsPush273 AutoComplete;274 WinBorder;275 WinMax;276 DocClear;277 "$BK,1$Move things around.$BK,0$\n";278 pf=Init;279 tmpo=NULL;280 Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS281 -WIF_SELF_CTRLS-WIF_FOCUS_TASK_MENU;282 Fs->draw_it=&DrawIt;283 try {284 while (TRUE) {285 switch (msg_code=GetMsg(&arg1,&arg2,286 1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_MOVE)) {287 case MSG_KEY_DOWN:288 switch (arg1) {289 case '\n':290 CleanUp(pf);291 pf=Init;292 tmpo=NULL;293 break;294 case CH_SHIFT_ESC:295 case CH_ESC:296 goto pd_done;297 }298 break;299 case MSG_MS_L_DOWN:300 tmpo=PPtFind(pf,arg1-pf->cx,arg2-pf->cy);301 break;302 case MSG_MS_L_UP:303 if (tmpo) {304 tmpo->p.p.x=arg1-pf->cx;305 tmpo->p.p.y=arg2-pf->cy;306 tmpo=NULL;307 }308 break;309 case MSG_MS_MOVE:310 if (tmpo) {311 tmpo->p.p.x=arg1-pf->cx;312 tmpo->p.p.y=arg2-pf->cy;313 }314 break;315 }316 }317pd_done:318 GetMsg(,,1<<MSG_KEY_UP);319 } catch320 PutExcept;321 SettingsPop;322 MenuPop;323 CleanUp(pf);324 FramePtrDel("PickFrame");325}326 327Pick3D;328 