templeos-info/public/Wb/Demo/Graphics/Pick3D.HC

329 lines
6.4 KiB
HolyC
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//This is a whimsical program which demonstrates some techniques.
#define BORDER 20
#define PTY_PT 0
#define PTY_CIRCLE 1
#define PTY_LINE 2
#define PTY_SPRITE 3
#define PTY_NUM 4
extern class PObj;
class PPt
{
CD3I32 p;
};
class PCircle
{
PObj *p;
I64 radius;
};
class PLine
{
PObj *p1,*p2;
};
class PCSprite
{
PObj *p;
U8 *img;
I64 *r,
*dr; //Rounding error might eventually screw this up
}
class PObj
{
PObj *next,*last;
I64 type,color;
union {
PPt p;
PCircle c;
PLine l;
PCSprite g;
};
};
class PickFrame
{
PObj o_head;
I64 o_cnts[PTY_NUM];
I64 cx,cy;
};
#define IMGS_NUM 3
$SP,"<1>",BI=1$
$SP,"<2>",BI=2$
$SP,"<3>",BI=3$
U8 *imgs[IMGS_NUM]={$IB,"<1>",BI=1$,$IB,"<2>",BI=2$,$IB,"<3>",BI=3$};
U0 DrawIt(CTask *task,CDC *dc)
{
I64 *r,*old_r;
PickFrame *pf=FramePtr("PickFrame",task);
PObj *tmpo=pf->o_head.next;
pf->cx=task->pix_width>>1;
pf->cy=task->pix_height>>1;
DCDepthBufAlloc(dc);
dc->color=LTRED;
dc->thick=3;
GrBorder(dc,BORDER,BORDER,2*pf->cx-BORDER,2*pf->cy-BORDER);
while (tmpo!=&pf->o_head) {
dc->color=tmpo->color;
switch (tmpo->type) {
case PTY_PT:
GrLine(dc,pf->cx+tmpo->p.p.x+2,pf->cy+tmpo->p.p.y+2,
pf->cx+tmpo->p.p.x-2,pf->cy+tmpo->p.p.y-2);
GrLine(dc,pf->cx+tmpo->p.p.x-2,pf->cy+tmpo->p.p.y+2,
pf->cx+tmpo->p.p.x+2,pf->cy+tmpo->p.p.y-2);
break;
case PTY_CIRCLE:
GrCircle(dc,pf->cx+tmpo->c.p->p.p.x,pf->cy+tmpo->c.p->p.p.y,
tmpo->c.radius);
break;
case PTY_LINE:
GrLine(dc,pf->cx+tmpo->l.p1->p.p.x,pf->cy+tmpo->l.p1->p.p.y,
pf->cx+tmpo->l.p2->p.p.x,pf->cy+tmpo->l.p2->p.p.y);
break;
case PTY_SPRITE:
old_r=dc->r;
dc->r=tmpo->g.r;
dc->x=pf->cx+tmpo->g.p->p.p.x;
dc->y=pf->cy+tmpo->g.p->p.p.y;
dc->z=GR_Z_ALL;
dc->flags|=DCF_TRANSFORMATION;
Sprite3(dc,0,0,0,tmpo->g.img);
dc->flags&=~DCF_TRANSFORMATION;
dc->r=old_r;
//Updated each refresh, not guarenteed to be uniform.
//Rounding error might corrupt, as well.
r=Mat4x4MulMat4x4New(tmpo->g.dr,tmpo->g.r,task);
Free(tmpo->g.r);
tmpo->g.r=r;
break;
}
tmpo=tmpo->next;
}
}
PObj *PObjNew(PickFrame *pf,I64 type,I64 color)
{
PObj *tmpo=CAlloc(sizeof(PObj));
tmpo->type=type;
tmpo->color=color;
pf->o_cnts[type]++;
QueIns(tmpo,pf->o_head.last);
return tmpo;
}
U0 PObjDel(PickFrame *pf,PObj *tmpo)
{
QueRem(tmpo);
switch (tmpo->type) {
case PTY_SPRITE:
Free(tmpo->g.r);
Free(tmpo->g.dr);
break;
}
pf->o_cnts[tmpo->type]--;
Free(tmpo);
}
PObj *PPtNew(PickFrame *pf,I64 x,I64 y)
{
PObj *tmpo=PObjNew(pf,PTY_PT,BLACK);
tmpo->p.p.x=x;
tmpo->p.p.y=y;
return tmpo;
}
PObj *PPtNum(PickFrame *pf,I64 num)
{
PObj *tmpo=pf->o_head.next;
while (tmpo!=&pf->o_head) {
if (tmpo->type==PTY_PT && !num--)
return tmpo;
tmpo=tmpo->next;
}
return NULL;
}
PObj *PPtFind(PickFrame *pf,I64 x,I64 y)
{
I64 dd,best_dd=I64_MAX;
PObj *tmpo=pf->o_head.next,*res=NULL;
while (tmpo!=&pf->o_head) {
if (tmpo->type==PTY_PT) {
dd=SqrI64(tmpo->p.p.x-x)+SqrI64(tmpo->p.p.y-y);
if (dd<best_dd) {
best_dd=dd;
res=tmpo;
}
}
tmpo=tmpo->next;
}
return res;
}
PObj *PCircleNew(PickFrame *pf,I64 p_num,I64 r)
{
PObj *tmpo=PObjNew(pf,PTY_CIRCLE,RED);
tmpo->c.p=PPtNum(pf,p_num);
tmpo->c.radius=r;
return tmpo;
}
PObj *PLineNew(PickFrame *pf,I64 p1_num,I64 p2_num)
{
PObj *tmpo=PObjNew(pf,PTY_LINE,GREEN);
tmpo->l.p1=PPtNum(pf,p1_num);
tmpo->l.p2=PPtNum(pf,p2_num);
return tmpo;
}
PObj *PCSpriteNew(PickFrame *pf,U8 *img,I64 p_num,I64 *r,I64 *dr)
{
PObj *tmpo=PObjNew(pf,PTY_SPRITE,BLACK);
tmpo->g.p=PPtNum(pf,p_num);
tmpo->g.img=img;
tmpo->g.r=r;
tmpo->g.dr=dr;
return tmpo;
}
PickFrame *Init()
{
PickFrame *pf=CAlloc(sizeof(PickFrame));
I64 i,*r,*dr;
pf->cx=Fs->pix_width>>1;
pf->cy=Fs->pix_height>>1;
pf->o_head.next=pf->o_head.last=&pf->o_head;
for (i=0;i<50;i++)
PPtNew(pf,RandI32%(pf->cx-BORDER),RandI32%(pf->cy-BORDER));
for (i=0;i<20;i++)
PCircleNew(pf,pf->o_cnts[PTY_PT]*RandU16/U16_MAX,6);
for (i=0;i<20;i++)
PLineNew(pf,pf->o_cnts[PTY_PT]*RandU16/U16_MAX,
pf->o_cnts[PTY_PT]*RandU16/U16_MAX);
for (i=0;i<10;i++) {
r=Mat4x4IdentNew;
dr=Mat4x4IdentNew;
Mat4x4RotZ(dr,0.05*2*(Rand-0.5));
Mat4x4RotY(dr,0.05*2*(Rand-0.5));
Mat4x4RotX(dr,0.05*2*(Rand-0.5));
PCSpriteNew(pf,imgs[IMGS_NUM*RandU16/U16_MAX],
pf->o_cnts[PTY_PT]*RandU16/U16_MAX,r,dr);
}
FramePtrSet("PickFrame",pf);
return pf;
}
U0 CleanUp(PickFrame *pf)
{
PObj *tmpo=pf->o_head.next,*tmpo1;
while (tmpo!=&pf->o_head) {
tmpo1=tmpo->next;
PObjDel(pf,tmpo);
tmpo=tmpo1;
}
Free(pf);
}
U0 Pick3D()
{
I64 msg_code,arg1,arg2;
PObj *tmpo;
PickFrame *pf=NULL;
FramePtrAdd("PickFrame");
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
"}"
);
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
AutoComplete;
WinBorder;
WinMax;
DocClear;
"$$BK,1$$Move things around.$$BK,0$$\n";
pf=Init;
tmpo=NULL;
Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
-WIF_SELF_CTRLS-WIF_FOCUS_TASK_MENU;
Fs->draw_it=&DrawIt;
try {
while (TRUE) {
switch (msg_code=GetMsg(&arg1,&arg2,
1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_MOVE)) {
case MSG_KEY_DOWN:
switch (arg1) {
case '\n':
CleanUp(pf);
pf=Init;
tmpo=NULL;
break;
case CH_SHIFT_ESC:
case CH_ESC:
goto pd_done;
}
break;
case MSG_MS_L_DOWN:
tmpo=PPtFind(pf,arg1-pf->cx,arg2-pf->cy);
break;
case MSG_MS_L_UP:
if (tmpo) {
tmpo->p.p.x=arg1-pf->cx;
tmpo->p.p.y=arg2-pf->cy;
tmpo=NULL;
}
break;
case MSG_MS_MOVE:
if (tmpo) {
tmpo->p.p.x=arg1-pf->cx;
tmpo->p.p.y=arg2-pf->cy;
}
break;
}
}
pd_done:
GetMsg(,,1<<MSG_KEY_UP);
} catch
PutExcept;
SettingsPop;
MenuPop;
CleanUp(pf);
FramePtrDel("PickFrame");
}
Pick3D;
z<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>