Files
TempleOS-Rijn/TempleOS/Demo/Graphics/Flowers.CPP
T
2018-09-08 21:45:37 +02:00

233 lines
4.5 KiB
C++

class Stem
{
Stem *next,*sub;
I64 x,y;
I64 flower_size;
};
class Seed
{
Seed *next;
Stem *sub;
I64 x,y;
I64 height,type;
Bool bloom;
} *seed_root;
F64 grow_speed=500.0,adjusted_grow_speed;
Bool GrowProbability(F64 prob)
{
return prob*adjusted_grow_speed>ToF64(RandU32)/MAX_U32;
}
$SP,"<1>",1$
I64 GrowStem(Stem *temps,I64 parent_x,I64 parent_y,I64 x0,I64 y0,Bool bloom)
{
I64 x,y,cnt=0,result=parent_y,height;
Stem *temps1,*temps2=temps;
while (temps) {
cnt++;
x=x0;
y=y0;
temps->x+=x;
temps->y+=y;
if (GrowProbability(0.40/(Abs(temps->y-parent_y)`.5+10.0))) {
temps->y++;
y++;
}
if (GrowProbability(0.15/(Abs(temps->x-parent_x)`.5+10.0))) {
if (2*SignI64(temps->x-parent_x)+SignI64(RandI16)<0) {
temps->x--;
x--;
} else {
temps->x++;
x++;
}
}
if (temps->y>result)
result=temps->y;
if (temps1=temps->sub)
height=GrowStem(temps1,temps->x,temps->y,x,y,bloom);
else {
if (!temps->flower_size && GrowProbability(0.003)) {
temps->sub=temps1=CAlloc(sizeof(Stem));
temps1->x=temps->x;
height=temps1->y=temps->y+1;
} else {
height=0;
if (!temps->next && cnt==1 && bloom && GrowProbability(0.01) && temps->flower_size<10)
temps->flower_size++;
}
}
if (height>result)
result=height;
temps=temps->next;
}
if (temps2 && !temps2->flower_size && GrowProbability(0.001/(cnt*cnt))) {
temps1=CAlloc(sizeof(Stem));
temps1->next=temps2->next;
temps2->next=temps1;
temps1->x=temps2->x+SignI64(RandI16);
temps1->y=temps2->y+1;
}
return result;
}
U0 GrowSeeds(Seed *tempe,I64,I64 h)
{
while (tempe) {
if (tempe->height<h)
tempe->height=GrowStem(tempe->sub,tempe->x,tempe->y,0,0,tempe->height>0.75*h);
tempe=tempe->next;
}
}
U0 DrawStem(CDC *dc,Seed *tempe,Stem *temps,Stem *parent,I64 w,I64 h)
{
I64 i;
dc->color=GREEN;
dc->pen_width=2;
while (temps) {
//We use $LK,"GrLine3","MN:GrLine3"$() because it has pen_width
if (parent) {
dc->color=GREEN;
dc->pen_width=2;
GrLine3(dc,temps->x+w/2,h-temps->y,0,parent->x+w/2,h-parent->y,0);
}
DrawStem(dc,tempe,temps->sub,temps,w,h);
if (temps->flower_size) {
for (i=0;i<temps->flower_size;i++) {
switch (tempe->type) {
case 0:
if (i&1)
dc->color=RED;
else
dc->color=YELLOW;
break;
case 1:
if (i&1)
dc->color=PURPLE;
else
dc->color=WHITE;
break;
case 2:
if (i&1)
dc->color=BLUE;
else
dc->color=PURPLE;
break;
case 3:
if (i&1)
dc->color=RED;
else
dc->color=WHITE;
break;
}
dc->pen_width=2;
GrCircle3(dc,temps->x+w/2,h-temps->y,0,i+1);
}
}
temps=temps->next;
}
}
U0 DrawSeeds(CDC *dc,Seed *tempe,I64 w,I64 h)
{
Stem *temps;
while (tempe) {
SpritePlot3(dc,tempe->x+w/2,h-tempe->y,0,$IB,"<1>",1$);
//We use $LK,"GrLine3","MN:GrLine3"$() because it has pen_width
if (temps=tempe->sub) {
dc->color=GREEN;
dc->pen_width=2;
GrLine3(dc,temps->x+w/2,h-temps->y,0,tempe->x+w/2,h-tempe->y,0);
DrawStem(dc,tempe,temps,temps,w,h);
}
tempe=tempe->next;
}
}
U0 DrawIt(CTask *task, CDC *dc)
{
adjusted_grow_speed=grow_speed/win_actual_refresh;
GrowSeeds(seed_root,task->win_pixel_width,task->win_pixel_height);
DrawSeeds(dc,seed_root,task->win_pixel_width,task->win_pixel_height);
}
U0 StemsDel(Stem *temps)
{
Stem *temps1;
while (temps) {
temps1=temps->next;
StemsDel(temps->sub);
Free(temps);
temps=temps1;
}
}
U0 SeedsDel(Seed *tempe)
{
Seed *tempe1;
while (tempe) {
tempe1=tempe->next;
StemsDel(tempe->sub);
Free(tempe);
tempe=tempe1;
}
}
Seed *SeedNew()
{
Seed *result=CAlloc(sizeof(Seed));
result->sub=CAlloc(sizeof(Stem));
result->type=RandU16&3;
result->x=result->sub->x=RandI32%(Fs->win_pixel_width/3);
return result;
}
U0 InitFlowers()
{
I64 i;
Seed **tempe=&seed_root;
SeedsDel(seed_root);
seed_root=NULL;
for (i=0;i<5;i++) {
*tempe=SeedNew;
tempe=&(*tempe)->next;
}
}
U0 Flowers()
{
I64 ch;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
Fs->draw_it=&DrawIt;
seed_root=NULL;
DocClear;
try
do {
//Hopefully draw_it will not happen during Init()
WinMgrSync;
InitFlowers;
ch=GetChar(NULL,FALSE);
} while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
catch
CatchAll;
SettingsPop;
SeedsDel(seed_root);
}
Flowers;
0þÿÿÿ¤ínHš¦ílÿÿÿÿþÿÿÿ´