TempleOSTS_140317.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:46:02 +02:00
1 parent 2d2a65d572
commit 7ef616a20e
1416 files changed
+223873 -53917

No files matched your search

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+767
View File
@@ -0,0 +1,767 @@
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
AcctRegSetDftEntry("TempleOS/CastleFrankenstein","F64 best_score=9999;\n");
AcctRegExeBranch("TempleOS/CastleFrankenstein");
//Set snap to 4 and width to 4
//if you edit this map.
//Don't forget to change the
//starting pos.
#define MAN_START_X 0
#define MAN_START_Y 4.5
$SP,"<1>",BI=1$
#define MONSTER_SCALE 2.0
$SP,"<2>",BI=2$
$SP,"<3>",BI=3$
$SP,"<4>",BI=4$
#define PLANT_SCALE 2.0
$SP,"<5>",BI=5$
$SP,"<6>",BI=6$
#define SCREEN_SCALE 512
#define PLOT_GRID_WIDTH 24
#define PLOT_GRID_HEIGHT 24
#define MAN_HEIGHT 125
#define MAP_SCALE 4
I64 map_width,map_height;
U8 *map=NULL,
*panels_processed_bitmap=NULL;
I64 man_xx,man_yy;
F64 man_é;
F64 t0,tf;
#define NUM_MONSTERS 16
I64 monsters_left;
class Monster
{
I64 x,y;
Bool dead,pad[7];
} monsters[NUM_MONSTERS];
U0 CFTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
{
I64 zz;
GrRot(dc->r,x,y,z);
zz=SCREEN_SCALE/3+*z;
if (zz<1) zz=1;
*x=SCREEN_SCALE/2* *x/zz;
*y=SCREEN_SCALE/2* (*y+MAN_HEIGHT)/zz;
*x+=dc->x;
*y+=dc->y;
*z+=dc->z;
}
#define LOS_SCALE 4
Bool LOSPlot(U8 *,I64 x,I64 y,I64)
{
if (!map[(y/LOS_SCALE)*map_width+(x/LOS_SCALE)])
return FALSE;
else
return TRUE;
}
Bool LOS(I64 x1,I64 y1,I64 x2,I64 y2)
{ //Line of sight
return Line(NULL,x1*LOS_SCALE/SCREEN_SCALE,y1*LOS_SCALE/SCREEN_SCALE,0,
x2*LOS_SCALE/SCREEN_SCALE,y2*LOS_SCALE/SCREEN_SCALE,0,&LOSPlot);
}
U0 DrawIt(CTask *task,CDC *dc)
{
I64 i,j,*r1,*r2,*r3,*s2w,xx,yy,zz,x,y,x1,y1,z1,
c,x1w,y1w,x1h,y1h,xh,yh,zh,
cx=task->pix_width/2,
cy=task->pix_height/2;
CSprite *temps;
F64 tt;
CD3I32 poly[4];
DCAllocDepthBuf(dc);
MemSet(panels_processed_bitmap,0,(map_width*map_height+7)>>3);
//World to screen
GrRotZEqu(dc->r,man_é+ã/2);
GrRotXEqu(dc->r,ã/2);
GrSetRotMat(dc,dc->r);
xh=-man_xx/SCREEN_SCALE; yh=-man_yy/SCREEN_SCALE; zh=0;
GrRot(dc->r,&xh,&yh,&zh);
GrSetTranslation(dc->r,xh,yh,zh);
//Screen to world
s2w=GrRotXNew(-ã/2,task);
GrRotZEqu(s2w,-man_é-ã/2);
xh=0; yh=0; zh=SCREEN_SCALE;
GrRot(s2w,&xh,&yh,&zh);
//Rotate light source
xx=dc->ls.x; yy=dc->ls.y; zz=-dc->ls.z;
(*dc->transform)(dc,&xx,&yy,&zz);
dc->ls.x=xx; dc->ls.y=yy; dc->ls.z=zz;
dc->flags|=DCF_TRANSFORMATION;
dc->transform=&CFTransform;
dc->x=cx;
dc->y=cy;
r1=GrRotXNew(-ã/2,task);
GrRotZEqu(r1,tS);
GrScaleEqu(r1,MONSTER_SCALE);
r2=GrIdentNew(task);
GrScaleEqu(r2,MONSTER_SCALE);
r3=GrRotXNew(-ã/2,task);
GrScaleEqu(r3,PLANT_SCALE);
x1h=man_xx+yh*PLOT_GRID_WIDTH/2+xh*(PLOT_GRID_HEIGHT-1);
y1h=man_yy-xh*PLOT_GRID_WIDTH/2+yh*(PLOT_GRID_HEIGHT-1);
xh>>=1; yh>>=1;
for (j=0;j<PLOT_GRID_HEIGHT*2;j++) {
x1w=x1h;
y1w=y1h;
for (i=0;i<PLOT_GRID_WIDTH*4;i++) {
xx=x1w/SCREEN_SCALE; yy=y1w/SCREEN_SCALE;
x=xx*SCREEN_SCALE-man_xx; y=yy*SCREEN_SCALE-man_yy;
if (1<=xx<map_width-1 && 1<=yy<map_height-1 &&
!LBts(panels_processed_bitmap,yy*map_width+xx)) {
if ((c=map[yy*map_width+xx]) &&
LOS(xx*SCREEN_SCALE+SCREEN_SCALE/2,yy*SCREEN_SCALE+SCREEN_SCALE/2,
man_xx,man_yy)) {
if (c==YELLOW)
dc->color=RED;
else
dc->color=c;
poly[0].x=x;
poly[0].y=y;
poly[0].z=0;
poly[1].x=x+SCREEN_SCALE;
poly[1].y=y;
poly[1].z=0;
poly[2].x=x+SCREEN_SCALE;
poly[2].y=y+SCREEN_SCALE;
poly[2].z=0;
poly[3].x=x;
poly[3].y=y+SCREEN_SCALE;
poly[3].z=0;
GrFillPoly3(dc,4,poly);
if (c==GREEN) {
x1=x+SCREEN_SCALE/2;
y1=y+SCREEN_SCALE/2;
z1=0;
GrTransform(dc,&x1,&y1,&z1);
if (z1>0)
SpriteMat3B(dc,x+SCREEN_SCALE/2,y+SCREEN_SCALE/2,0,$IB,"<5>",BI=5$,r3);
} else if (c==YELLOW) {
x1=x+SCREEN_SCALE/2;
y1=y+SCREEN_SCALE/2;
z1=0;
GrTransform(dc,&x1,&y1,&z1);
if (z1>0)
SpriteMat3B(dc,x+SCREEN_SCALE/2,y+SCREEN_SCALE/2,0,$IB,"<6>",BI=6$,r3);
}
if (!map[(yy+1)*map_width+xx]) {
dc->color=LTGRAY;
poly[0].x=x;
poly[0].y=y+SCREEN_SCALE;
poly[0].z=0;
poly[1].x=x+SCREEN_SCALE;
poly[1].y=y+SCREEN_SCALE;
poly[1].z=0;
poly[2].x=x+SCREEN_SCALE;
poly[2].y=y+SCREEN_SCALE;
poly[2].z=SCREEN_SCALE;
poly[3].x=x;
poly[3].y=y+SCREEN_SCALE;
poly[3].z=SCREEN_SCALE;
GrFillPoly3(dc,4,poly);
}
if (!map[yy*map_width+xx+1]) {
dc->color=DKGRAY;
poly[0].x=x+SCREEN_SCALE;
poly[0].y=y;
poly[0].z=0;
poly[1].x=x+SCREEN_SCALE;
poly[1].y=y+SCREEN_SCALE;
poly[1].z=0;
poly[2].x=x+SCREEN_SCALE;
poly[2].y=y+SCREEN_SCALE;
poly[2].z=SCREEN_SCALE;
poly[3].x=x+SCREEN_SCALE;
poly[3].y=y;
poly[3].z=SCREEN_SCALE;
GrFillPoly3(dc,4,poly);
}
if (!map[(yy-1)*map_width+xx]) {
dc->color=LTGRAY;
poly[0].x=x;
poly[0].y=y;
poly[0].z=0;
poly[1].x=x+SCREEN_SCALE;
poly[1].y=y;
poly[1].z=0;
poly[2].x=x+SCREEN_SCALE;
poly[2].y=y;
poly[2].z=SCREEN_SCALE;
poly[3].x=x;
poly[3].y=y;
poly[3].z=SCREEN_SCALE;
GrFillPoly3(dc,4,poly);
}
if (!map[yy*map_width+xx-1]) {
dc->color=DKGRAY;
poly[0].x=x;
poly[0].y=y;
poly[0].z=0;
poly[1].x=x;
poly[1].y=y+SCREEN_SCALE;
poly[1].z=0;
poly[2].x=x;
poly[2].y=y+SCREEN_SCALE;
poly[2].z=SCREEN_SCALE;
poly[3].x=x;
poly[3].y=y;
poly[3].z=SCREEN_SCALE;
GrFillPoly3(dc,4,poly);
}
}
}
x1w-=yh;
y1w+=xh;
}
x1h-=xh;
y1h-=yh;
}
//Draw Monsters
for (i=0;i<NUM_MONSTERS;i++) {
x=monsters[i].x;
y=monsters[i].y;
if (LOS(x,y,man_xx,man_yy)) {
x-=man_xx;
y-=man_yy;
xx=x;
yy=y;
zz=0;
GrTransform(dc,&xx,&yy,&zz);
if (zz>0) {
if (monsters[i].dead)
SpriteMat3B(dc,x,y,0,$IB,"<2>",BI=2$,r2);
else {
tt=Tri(tS,1.0);
temps=SpriteInterpolate($IB,"<3>",BI=3$,$IB,"<4>",BI=4$,tt);
SpriteMat3B(dc,x,y,0,temps,r1);
Free(temps);
}
}
}
}
Free(r1);
Free(r2);
Free(r3);
//Draw Map heads-up display, scaled 2 pixs
Free(dc->r);
GrSetRotMat(dc,GrIdentNew(task));
dc->x=task->pix_width -2*map_width;
dc->y=task->pix_height-2*map_height;
dc->z=0;
dc->transform=&GrTransform;
dc->pen_width=2;
for (i=0;i<map_height;i++)
for (j=0;j<map_width;j++) {
dc->color=map[(map_height-1-i)*map_width+j];
GrPlot3(dc,2*j,2*i,0);
}
//Draw Things on heads-up Map
dc->color=LTPURPLE;
for (i=0;i<NUM_MONSTERS;i++)
if (!monsters[i].dead)
GrPlot3(dc,2*(monsters[i].x/SCREEN_SCALE),2*(map_height-1-monsters[i].y/SCREEN_SCALE),0);
dc->color=LTCYAN;
GrPlot3(dc,2*(man_xx/SCREEN_SCALE),2*(map_height-1-man_yy/SCREEN_SCALE),0);
if (tf) {
dc->color=LTRED;
if (Blink)
GrPrint(dc,cx-(FONT_WIDTH*14)/2,cy-FONT_HEIGHT/2,"Game Completed");
tt=tf;
} else {
dc->color=LTGREEN;
GrLine(dc,cx-5,cy,cx+5,cy);
GrLine(dc,cx,cy-5,cx,cy+5);
tt=tS;
}
GrPrint(dc,0,0,"Enemy:%d Time:%3.2f Best:%3.2f",monsters_left,tt-t0,best_score);
Free(s2w);
}
U0 Fire()
{
I64 i,x,y;
F64 d,dx,dy,xx=Cos(man_é),yy=Sin(man_é);
Noise(100,300,1000);
for (i=0;i<NUM_MONSTERS;i++) {
x=monsters[i].x;
y=monsters[i].y;
if (!monsters[i].dead &&
LOS(x,y,man_xx,man_yy)) {
dx=x-man_xx;
dy=man_yy-y;
if (d=Sqrt(dx*dx+dy*dy)) {
dx/=d;
dy/=d;
if (dx*xx+dy*yy>0.995) {
monsters[i].dead=TRUE;
if (!--monsters_left) {
tf=tS;
if (tf-t0<best_score)
best_score=tf-t0;
}
}
}
}
}
}
U0 Init()
{
I64 i,x,y;
I64 min_map_x,max_map_x,min_map_y,max_map_y;
CDC *dc;
DocClear;
"$$BG,BLACK$$"; NewLine(TEXT_ROWS/2);
SpriteExtents($IB,"<1>",BI=1$,&min_map_x,&max_map_x,&min_map_y,&max_map_y);
map_width =(max_map_x-min_map_x+1)/MAP_SCALE+2;
map_height=(max_map_y-min_map_y+1)/MAP_SCALE+2;
Free(map);
Free(panels_processed_bitmap);
map=CAlloc(map_width*map_height*sizeof(U8));
panels_processed_bitmap=MAlloc((map_width*map_height+7)>>3);
dc=DCNew(map_width*MAP_SCALE,map_height*MAP_SCALE);
Sprite3(dc,-min_map_x+MAP_SCALE,-min_map_y+MAP_SCALE,0,$IB,"<1>",BI=1$);
for (y=1;y<map_height-1;y++)
for (x=1;x<map_width-1;x++)
map[(map_height-1-y)*map_width+x]=GrPeek(dc,x*MAP_SCALE,y*MAP_SCALE);
DCDel(dc);
man_xx=(1+MAN_START_X)*SCREEN_SCALE;
man_yy=(map_height-1-MAN_START_Y)*SCREEN_SCALE;
man_é=0;
for (i=0;i<NUM_MONSTERS;i++) {
monsters[i].dead=FALSE;
do {
monsters[i].x=RandU64%((map_width-2)*SCREEN_SCALE)+SCREEN_SCALE;
monsters[i].y=RandU64%((map_height-2)*SCREEN_SCALE)+SCREEN_SCALE;
} while (!map[(monsters[i].y/SCREEN_SCALE)*map_width+monsters[i].x/SCREEN_SCALE]);
}
monsters_left=NUM_MONSTERS;
tf=0;
t0=tS;
}
U0 AnimateTask(I64)
{
I64 i,x,y,dd;
while (TRUE) {
dd=0.25*SCREEN_SCALE*Sin(tS/2);
for (i=0;i<NUM_MONSTERS;i++)
if (!monsters[i].dead) {
x=monsters[i].x;
y=monsters[i].y;
if (i&1)
x+=dd;
else
y+=dd;
if (0<=x<=map_width*SCREEN_SCALE &&
0<=y<=map_height*SCREEN_SCALE &&
map[(y/SCREEN_SCALE)*map_width+x/SCREEN_SCALE]) {
if (!map[(y/SCREEN_SCALE)*map_width+x/SCREEN_SCALE+1] &&
x-RoundI64(x,SCREEN_SCALE)>SCREEN_SCALE/2 ||
!map[(y/SCREEN_SCALE)*map_width+x/SCREEN_SCALE-1] &&
x-RoundI64(x,SCREEN_SCALE)<SCREEN_SCALE/2)
x=RoundI64(x,SCREEN_SCALE)+SCREEN_SCALE/2;
if (!map[(y/SCREEN_SCALE+1)*map_width+x/SCREEN_SCALE] &&
y-RoundI64(y,SCREEN_SCALE)>SCREEN_SCALE/2 ||
!map[(y/SCREEN_SCALE-1)*map_width+x/SCREEN_SCALE] &&
y-RoundI64(y,SCREEN_SCALE)<SCREEN_SCALE/2)
y=RoundI64(y,SCREEN_SCALE)+SCREEN_SCALE/2;
monsters[i].x=x;
monsters[i].y=y;
}
}
Sleep(20);
}
}
U0 CleanUp()
{
Free(map);
Free(panels_processed_bitmap);
map=NULL;
panels_processed_bitmap=NULL;
}
U0 SongTask(I64)
{ //Song by Terry A. Davis
Fs->task_end_cb=&SndTaskEndCB;
MusicSettingsRst;
while (TRUE) {
Play("2q.A#1eG2AeA#qAq.A#1eG2eAeA#qA");
Play("q.A#1eG2A#A1qG2q.A#1eG2A#A1qG");
Play("3eA#A2qG3eA#A2qG3eA#A2G3AA#A2qG");
}
}
U0 MoveMan(F64 é)
{
I64 x,y,color,step=SCREEN_SCALE/2;
do {
x=man_xx+step*Cos(é);
y=man_yy-step*Sin(é);
x=Clamp(x,0,map_width*SCREEN_SCALE);
y=Clamp(y,0,map_height*SCREEN_SCALE);
color=map[y/SCREEN_SCALE*map_width+x/SCREEN_SCALE];
if (color==RED || color==GREEN) {
man_xx=x;
man_yy=y;
break;
} else
step>>=1;
} while (step);
}
#define MICRO_STEPS 4
U0 RotateMan(F64 d)
{
I64 i;
for (i=0;i<MICRO_STEPS;i++) {
man_é+=d/MICRO_STEPS;
Sleep(15);
}
}
U0 CastleFrankenstein()
{
I64 sc;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" Fwd(,,SC_CURSOR_UP);"
" Backward(,,SC_CURSOR_DOWN);"
" Left(,,SC_CURSOR_LEFT);"
" Right(,,SC_CURSOR_RIGHT);"
" Fire(,CH_SPACE);"
"}"
);
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
Fs->text_attr=RED<<4+WHITE;
Preempt(OFF);
WinBorder;
WinMax;
WordStat;
Init;
Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
DocCursor;
Fs->draw_it=&DrawIt;
try {
while (TRUE) {
switch (GetKey(&sc)) {
case CH_SPACE:
Fire;
break;
case '\n':
Init;
break;
case CH_ESC:
case CH_SHIFT_ESC:
goto fs_done;
case 0:
switch (sc.u8[0]) {
case SC_CURSOR_RIGHT:
Spawn(&RotateMan,(ã/32)(I64));
break;
case SC_CURSOR_LEFT:
Spawn(&RotateMan,(-ã/32)(I64));
break;
case SC_CURSOR_UP:
MoveMan(man_é);
break;
case SC_CURSOR_DOWN:
MoveMan(man_é+ã);
break;
}
break;
}
}
fs_done:
} catch
PutExcept;
DocClear;
SettingsPop;
CleanUp;
MenuPop;
AcctRegWriteBranch("TempleOS/CastleFrankenstein","F64 best_score=%5.4f;\n",best_score);
}
CastleFrankenstein;
+
 
 
<
<<
< 
,,,
$8
88
8$
$$
$4
44
4 (
( (
(0
,0T0
T0TL
TL,L
,L,4
04P4
P4PH
PH0H
0H08
08L8
L8LD
LD4D
4D4<
4<H<
H<H@
H@8@
T@l@
l4lL
lLˆL
ˆLˆ$
ˆ$€$
€$€0
€0l0
p4„4
„(„H
€HpH
pDp8
p8€8
€8€D
€DtH
tDt<
t<|<
x@|@
|DxD
„ „
„t
pp
p\
\\
\l
lh
ll
l`
``
`d
dd
h h
XT
PP
PL
LL
(@@
8H
HH
H8
88
8D
D D
D < Z,u
@ Z
DD<
DDD\
D\DdT0T8THL0LLd d hh88x8|8|4x4tt$t@8HLL,L4L<LZ<HñÿÿÿñÿÿÿØÿÿÿìÿÿÿØÿÿÿûÿÿÿ¿ÿÿÿ¿ÿÿÿØÿÿÿØÿÿÿìÿÿÿƒÿÿÿçÿÿÿƒÿÿÿûÿÿÿƒÿÿÿƒÿÿÿ
tÿÿÿöÿÿÿtÿÿÿ
¿ÿÿÿöÿÿÿ¿ÿÿÿƒÿÿÿ
tÿÿÿ
ƒÿÿÿ
ûÿÿÿƒÿÿÿ
çÿÿÿƒÿÿÿ
¿ÿÿÿ
¿ÿÿÿ
ûÿÿÿ¿ÿÿÿ
öÿÿÿ¿ÿÿÿ
ìÿÿÿØÿÿÿ
ñÿÿÿØÿÿÿ
Øÿÿÿ
Øÿÿÿ
ûÿÿÿ
ûÿÿÿ
ñÿÿÿûÿÿÿ
ìÿÿÿûÿÿÿ
ƒÿÿÿ
ìÿÿÿƒÿÿÿ
çÿÿÿ«ÿÿÿ-ìÿÿÿ«ÿÿÿ-«ÿÿÿ-«ÿÿÿ-°ÿÿÿ-°ÿÿÿ-ìÿÿÿ°ÿÿÿ-çÿÿÿ°ÿÿÿ-øÿÿÿxÿÿÿ ýÿÿÿ|ÿÿÿ xÿÿÿ xÿÿÿ |ÿÿÿ öÿÿÿtÿÿÿ
ÿÿÿÿxÿÿÿ ìÿÿÿûÿÿÿñÿÿÿûÿÿÿñÿÿÿûÿÿÿûÿÿÿìÿÿÿ
 ␍    !!&''"#%$$#    ␍ ␍!


 $%*$*+'&('()&(( $++
0/.112-,7 765343! 3 45833!839;:7;766;;1␍Z<HñÿÿÿöÿÿÿñÿÿÿØÿÿÿìÿÿÿØÿÿÿûÿÿÿ¿ÿÿÿ¿ÿÿÿØÿÿÿØÿÿÿìÿÿÿöÿÿÿƒÿÿÿçÿÿÿƒÿÿÿûÿÿÿƒÿÿÿƒÿÿÿ
tÿÿÿöÿÿÿtÿÿÿ
¿ÿÿÿöÿÿÿ¿ÿÿÿƒÿÿÿ
tÿÿÿ
ƒÿÿÿ
ûÿÿÿƒÿÿÿ
çÿÿÿƒÿÿÿ
¿ÿÿÿ
¿ÿÿÿ
ûÿÿÿ¿ÿÿÿ
öÿÿÿ¿ÿÿÿ
ìÿÿÿØÿÿÿ
ñÿÿÿØÿÿÿ
Øÿÿÿ
Øÿÿÿ
ûÿÿÿûÿÿÿñÿÿÿûÿÿÿìÿÿÿûÿÿÿƒÿÿÿ
ìÿÿÿƒÿÿÿ
çÿÿÿ«ÿÿÿ-ìÿÿÿ«ÿÿÿ-«ÿÿÿÓÿÿÿ«ÿÿÿÓÿÿÿ°ÿÿÿÓÿÿÿ°ÿÿÿÓÿÿÿìÿÿÿ°ÿÿÿ-çÿÿÿ°ÿÿÿ-øÿÿÿxÿÿÿ ýÿÿÿ|ÿÿÿ xÿÿÿ xÿÿÿ |ÿÿÿ öÿÿÿtÿÿÿ
ÿÿÿÿxÿÿÿ ìÿÿÿûÿÿÿñÿÿÿûÿÿÿñÿÿÿûÿÿÿ-ûÿÿÿ-ìÿÿÿ--
 ␍    !!&''"#%$$#    ␍ ␍!


 $%*$*+'&('()&(( $++
0/.112-,7 765343! 3 45833!839;:7;766;;1␍Z<HñÿÿÿñÿÿÿØÿÿÿìÿÿÿØÿÿÿûÿÿÿ¿ÿÿÿ¿ÿÿÿØÿÿÿØÿÿÿìÿÿÿöÿÿÿƒÿÿÿçÿÿÿƒÿÿÿûÿÿÿƒÿÿÿƒÿÿÿ
tÿÿÿöÿÿÿtÿÿÿ
¿ÿÿÿöÿÿÿ¿ÿÿÿƒÿÿÿ
tÿÿÿ
ƒÿÿÿ
ûÿÿÿƒÿÿÿ
çÿÿÿƒÿÿÿ
¿ÿÿÿ
¿ÿÿÿ
ûÿÿÿ¿ÿÿÿ
öÿÿÿ¿ÿÿÿ
ìÿÿÿØÿÿÿ
ñÿÿÿØÿÿÿ
Øÿÿÿ
Øÿÿÿ
ûÿÿÿûÿÿÿñÿÿÿûÿÿÿìÿÿÿûÿÿÿƒÿÿÿ
ìÿÿÿƒÿÿÿ
çÿÿÿ«ÿÿÿÓÿÿÿìÿÿÿ«ÿÿÿÓÿÿÿ«ÿÿÿ-«ÿÿÿ-°ÿÿÿ-°ÿÿÿ-ìÿÿÿ°ÿÿÿÓÿÿÿçÿÿÿ°ÿÿÿÓÿÿÿøÿÿÿxÿÿÿ ýÿÿÿ|ÿÿÿ xÿÿÿ xÿÿÿ |ÿÿÿ öÿÿÿtÿÿÿ
ÿÿÿÿxÿÿÿ ìÿÿÿûÿÿÿ#ñÿÿÿûÿÿÿ#ñÿÿÿ#ûÿÿÿûÿÿÿìÿÿÿ#öÿÿÿ
 ␍    !!&''"#%$$#    ␍ ␍!


 $%*$*+'&('()&(( $++
0/.112-,7 765343! 3 45833!839;:7;766;;1␍,ÎÿÿÿÎÿÿÿûÿÿÿçÿÿÿûÿÿÿçÿÿÿµÿÿÿ�ÿÿÿƒÿÿÿ�ÿÿÿâÿÿÿµÿÿÿâÿÿÿûÿÿÿÎÿÿÿûÿÿÿÎÿÿÿûÿÿÿûÿÿÿçÿÿÿûÿÿÿûÿÿÿçÿÿÿûÿÿÿµÿÿÿûÿÿÿ�ÿÿÿûÿÿÿ�ÿÿÿâÿÿÿûÿÿÿµÿÿÿâÿÿÿ�ÿÿÿµÿÿÿâÿÿÿµÿÿÿâÿÿÿ�ÿÿÿ�ÿÿÿûÿÿÿµÿÿÿûÿÿÿâÿÿÿµÿÿÿûÿÿÿâÿÿÿ�ÿÿÿûÿÿÿ 


  ␍␍ ␍ 
 

 ␍
␍÷ÿÿÿ÷ÿÿÿñÿÿÿ÷ÿÿÿ ôÿÿÿ ÷ÿÿÿ øÿÿÿçÿÿÿìÿÿÿçÿÿÿìÿÿÿçÿÿÿøÿÿÿøÿÿÿçÿÿÿðÿÿÿçÿÿÿðÿÿÿçÿÿÿøÿÿÿçÿÿÿçÿÿÿ   ␍ ␍ 
   


   ␍ ␍␍(Øÿÿÿ(ØÿÿÿØÿÿÿØÿÿÿìÿÿÿÎÿÿÿÎÿÿÿìÿÿÿ‚‚ìÿÿÿ‚ìÿÿÿìÿÿÿ‚öÿÿÿâÿÿÿ‚
âÿÿÿ‚ìÿÿÿ  


  

     ␍␍ ␍  
Binary file not shown.
+128
View File
@@ -0,0 +1,128 @@
//Practice tracing circles
//Giotto, a famous artist, drew a freehand circle as a portfolio for a job.
AcctRegSetDftEntry("TempleOS/CircleTrace","F64 best_score=999;\n");
AcctRegExeBranch("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("hEDCARCDECR");
}
U0 DrawIt(CTask *task,CDC *)
{
U8 buf[128];
SPrint(buf,"Error:%6.3f Time:%6.3f Score:%6.3f Best:%8.3f",avg_error,elapsed_time,score,best_score);
PlotWinStr(task,buf,BLACK<<4+WHITE,0,0);
}
#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,p1,p2,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);
WordStat;
cx=Fs->pix_width/2;
cy=Fs->pix_height/2;
Fs->win_inhibit=WIG_TASK_DFT-WIF_FOCUS-WIF_BORDER;
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
DCFill;
dc->color=ROP_XOR+BLACK^COLOR_TRANSPARENT;
GrCircle(dc,cx,cy,CIRCLE_RADIUS);
do {
msg_code=GetMsg(&p1,&p2,
1<<MSG_KEY_DOWN+1<<MSG_IP_L_DOWN);
switch (msg_code) {
case MSG_KEY_UP:
break;
case MSG_IP_L_DOWN:
DCFill;
dc->color=ROP_XOR+BLACK^COLOR_TRANSPARENT;
GrCircle(dc,cx,cy,CIRCLE_RADIUS);
dc->color=ROP_XOR+RED^COLOR_TRANSPARENT;
t0=tS;
total_distance=0.001;
total_error=0;
x1=p1; y1=p2;
do {
msg_code=ScanMsg(&p1,&p2,
1<<MSG_IP_L_UP+1<<MSG_IP_MOVE);
switch (msg_code) {
case MSG_IP_L_UP:
break;
case MSG_IP_MOVE:
if (x1!=p1 || y1!=p2) {
total_distance+=Sqrt(Sqr(x1-p1)+Sqr(y1-p2));
Line(dc,x1,y1,0,p1,p2,0,&CTPlot);
x1=p1;y1=p2;
//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;
//This $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.
WinMgrSync;
} while (msg_code!=MSG_IP_L_UP);
music_mute=TRUE; Sleep(200);
if (total_distance>0.95*CIRCUMFERENCE) {
if (score<best_score) {
Snd(2000);Sleep(50);Snd(0);Sleep(50);
Snd(2000);Sleep(50);Snd(0);Sleep(50);
Snd(2000);Sleep(50);
best_score=score;
} else {
Snd(500);Sleep(50);
}
} else {
Snd(100);Sleep(1000);
}
Snd(0); Sleep(200); music_mute=FALSE;
break;
}
} while (msg_code!=MSG_KEY_DOWN || p1!=CH_SHIFT_ESC && p1!=CH_ESC);
GetMsg(,,1<<MSG_KEY_UP);
SettingsPop;
DCFill;
DCDel(dc);
AcctRegWriteBranch("TempleOS/CircleTrace","F64 best_score=%5.4f;\n",best_score);
}
CircleTrace; //Execute when #included
Binary file not shown.
Binary file not shown.
+80
View File
@@ -0,0 +1,80 @@
//This loads a lst of zero terminated
//strings into the sym table and
//gives a name to it. Strings like
//this are known as Define entries.
//See $LK,"ST_RAINBOW_10",A="FF:::/Adam/Gr/GrPalette.CPP,ST_RAINBOW_10"$
U0 PrintDigit(U8 ch)
{
//The %Z code displays a Define subentry
if ('0'<=ch<='9')
"$$FG,%Z$$%d$$FG$$",ch-'0',"ST_RAINBOW_10",ch-'0';
}
U0 PrintPattern(U8 *st)
{
I64 ch;
while (ch=*st++)
PrintDigit(ch);
NewLine;
}
U0 Digits()
{
I64 num,ch,i;
U8 answer[1024];
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
Fs->text_attr=DKGRAY<<4+WHITE;
DocClear;
//Set default background and foreground
"$$WW,1$$$$BD,DKGRAY$$$$FD,WHITE$$"
"\nThis is a mem game. "
"Try to remember the digits and enter them. "
"They are colored based on electrical "
"engineering color codes.\n";
for (i=0;i<10;i++)
"$$FG,%Z$$%d: %Z\n",i,"ST_RAINBOW_10",i,i,"ST_RAINBOW_10";
"$$FG$$\n"; //set to default background
ch=PressAKey;
if (ch==CH_ESC||ch==CH_SHIFT_ESC) goto dg_done;
while (TRUE) {
restart:
num=0;
//Set to zeros so we have terminators
MemSet(answer,0,sizeof(answer));
while (TRUE) {
DocClear;
"$$WW,1$$$$BD,DKGRAY$$$$FD,WHITE$$\n";
"Pattern\nLength:%d\n\n",num+1;
answer[num++]=RandU32%10+'0';
PrintPattern(answer);
ch=PressAKey;
if (ch==CH_ESC||ch==CH_SHIFT_ESC) goto dg_done;
DocClear;
"$$WW,1$$$$BD,DKGRAY$$$$FD,WHITE$$\n";
"Guess\nLength:%d\n\n",num;
for (i=0;i<num;i++) {
ch=GetChar(,FALSE);
if (ch==CH_ESC||ch==CH_SHIFT_ESC) goto dg_done;
PrintDigit(ch);
if (ch!=answer[i]) {
"\nScore:%d\n",num;
PrintPattern(answer);
Beep; Beep;
ch=PressAKey;
if (ch==CH_ESC||ch==CH_SHIFT_ESC)
goto dg_done;
else
goto restart;
}
}
}
}
dg_done:
DocClear;
SettingsPop;
}
Digits;
+558
View File
@@ -0,0 +1,558 @@
//Set snap to 4 and width to 4
//if you edit this map.
//Don't forget to change the
//starting pos.
$BG,0$
$SP,"<1>",BI=1$
$SP,"<2>",BI=2$
$SP,"<3>",BI=3$
$SP,"<4>",BI=4$ //This is a template you can copy and use to make a tile.
$SP,"<5>",BI=5$
$SP,"<6>",BI=6$
$SP,"<7>",BI=7$
$SP,"<8>",BI=8$
$SP,"<9>",BI=9$
$SP,"<10>",BI=10$
$SP,"<11>",BI=11$
$BG$
//These are indexed by color #.
//See $LK,"COLORS",A="MN:RED"$.
U8 *tiles1[16]=
{NULL,$IB,"<7>",BI=7$ ,$IB,"<5>",BI=5$ ,NULL,
$IB,"<6>",BI=6$ ,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL};
U8 *tiles2[16]=
{NULL,$IB,"<8>",BI=8$ ,$IB,"<5>",BI=5$ ,NULL,
$IB,"<6>",BI=6$ ,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL};
#define SCREEN_SCALE 24
#define SCREEN_WIDTH 24
#define SCREEN_HEIGHT 24
I64 screen_x,screen_y;
#define MAP_SCALE 4
I64 map_width,map_height;
U8 *map=NULL;
I64 man_x,man_y,man_dx,man_dy;
Bool man_attack;
F64 man_attack_t0;
#define NUM_MONSTERS 16
class Monster
{
I64 x,y,dx,dy;
Bool dead,pad[7];
} monsters[NUM_MONSTERS];
#define LOS_SCALE 4
Bool LOSPlot(U8 *,I64 x,I64 y,I64)
{
if (!map[(y/LOS_SCALE)*map_width+(x/LOS_SCALE)])
return FALSE;
else
return TRUE;
}
Bool LOS(I64 x1,I64 y1,I64 x2,I64 y2)
{ //Line of sight
return Line(NULL,x1*LOS_SCALE+LOS_SCALE/2,y1*LOS_SCALE+LOS_SCALE/2,0,
x2*LOS_SCALE+LOS_SCALE/2,y2*LOS_SCALE+LOS_SCALE/2,0,&LOSPlot);
}
U0 DrawIt(CTask *task,CDC *dc)
{
CDC *dc_t=DCAlias(gr_dc2,task);
I64 i,x,y,xx,yy,x1,y1,z1,color;
CD3I32 poly[4];
U8 **_tiles;
if (Blink(5))
_tiles=tiles1;
else
_tiles=tiles2;
GrRotXEqu(dc_t->r,60*2*ã/360);
GrRotZEqu(dc_t->r,15*2*ã/360);
GrSetRotMat(dc_t,dc_t->r);
dc_t->x=task->pix_width/2;
dc_t->y=task->pix_height/2;
dc_t->flags|=DCF_TRANSFORMATION;
//You could make it much more efficient
//if you did it like $LK,"::/Demo/Games/BigGuns.CPP"$
//with a $LK,"CDC",A="MN:CDC"$.
for (y=-SCREEN_HEIGHT/2;y<SCREEN_HEIGHT/2;y++) {
yy=y+screen_y;
if (0<=yy<map_height)
for (x=-SCREEN_WIDTH/2;x<SCREEN_WIDTH/2;x++) {
xx=x+screen_x;
if (0<=xx<map_width) {
if ((color=map[yy*map_width+xx]) &&
LOS(xx,yy,man_x,man_y)) {
if (_tiles[color]) {
x1=x*SCREEN_SCALE;
y1=y*SCREEN_SCALE;
z1=0;
GrTransform(dc_t,&x1,&y1,&z1);
Sprite3(dc,x1,y1,z1,_tiles[color]);
} else { //If no tile defined, do solid color.
poly[0].x=x*SCREEN_SCALE;
poly[0].y=y*SCREEN_SCALE;
poly[0].z=0;
poly[1].x=(x+1)*SCREEN_SCALE-1;
poly[1].y=y*SCREEN_SCALE;
poly[1].z=0;
poly[2].x=(x+1)*SCREEN_SCALE;
poly[2].y=(y+1)*SCREEN_SCALE-1;
poly[2].z=0;
poly[3].x=x*SCREEN_SCALE-1;
poly[3].y=(y+1)*SCREEN_SCALE-1;
poly[3].z=0;
dc_t->color=color;
GrFillPoly3(dc_t,4,poly);
}
}
}
}
}
dc_t->color=LTGRAY;
for (x=-SCREEN_WIDTH/2;x<=SCREEN_WIDTH/2;x++)
GrLine3(dc_t,x*SCREEN_SCALE,-SCREEN_HEIGHT/2*SCREEN_SCALE,0,x*SCREEN_SCALE,SCREEN_HEIGHT/2*SCREEN_SCALE-1,0);
for (y=-SCREEN_HEIGHT/2;y<=SCREEN_HEIGHT/2;y++)
GrLine3(dc_t,-SCREEN_WIDTH/2*SCREEN_SCALE,y*SCREEN_SCALE,0,SCREEN_WIDTH/2*SCREEN_SCALE,y*SCREEN_SCALE-1,0);
for (y=-SCREEN_HEIGHT/2;y<SCREEN_HEIGHT/2;y++) {
yy=y+screen_y;
if (0<=yy<map_height)
for (x=-SCREEN_WIDTH/2;x<SCREEN_WIDTH/2;x++) {
xx=x+screen_x;
if (0<=xx<map_width) {
if (!map[yy*map_width+xx]) {
if (yy+1<map_height && LOS(xx,yy+1,man_x,man_y)) {
x1=x*SCREEN_SCALE;
y1=y*SCREEN_SCALE;
z1=0;
GrTransform(dc_t,&x1,&y1,&z1);
Sprite3(dc,x1,y1,z1,$IB,"<10>",BI=10$);
}
if (xx+1<map_width && LOS(xx+1,yy,man_x,man_y)) {
x1=x*SCREEN_SCALE;
y1=y*SCREEN_SCALE;
z1=0;
GrTransform(dc_t,&x1,&y1,&z1);
Sprite3(dc,x1,y1,z1,$IB,"<11>",BI=11$);
}
}
}
}
}
for (i=0;i<NUM_MONSTERS;i++)
if (!monsters[i].dead && LOS(monsters[i].x,monsters[i].y,man_x,man_y)) {
x1=(monsters[i].x-screen_x)*SCREEN_SCALE+SCREEN_SCALE/2;
y1=(monsters[i].y-screen_y)*SCREEN_SCALE+SCREEN_SCALE/2;
z1=0;
GrTransform(dc_t,&x1,&y1,&z1);
if (monsters[i].dx<0) {
dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
GrSetSymmetry(dc,x1,y1,x1,y1+1);
} else
dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
Sprite3(dc,x1,y1,z1,$IB,"<9>",BI=9$);
}
x1=(man_x-screen_x)*SCREEN_SCALE+SCREEN_SCALE/2;
y1=(man_y-screen_y)*SCREEN_SCALE+SCREEN_SCALE/2;
z1=0;
if (tS-man_attack_t0<0.2) {
x1+=Tri(tS-man_attack_t0,0.2)*SCREEN_SCALE*man_dx;
y1+=Tri(tS-man_attack_t0,0.2)*SCREEN_SCALE*man_dy;
}
GrTransform(dc_t,&x1,&y1,&z1);
if (man_dx<0) {
dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
GrSetSymmetry(dc,x1,y1,x1,y1+1);
} else
dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
if (tS-man_attack_t0<0.2)
Sprite3(dc,x1,y1,z1,$IB,"<3>",BI=3$);
else
Sprite3(dc,x1,y1,z1,$IB,"<2>",BI=2$);
DCDel(dc_t);
}
U0 Attack()
{
I64 i;
man_attack_t0=tS;
Noise(100,300,1000);
for (i=0;i<NUM_MONSTERS;i++) {
if (!monsters[i].dead &&
man_x+man_dx==monsters[i].x && man_y+man_dy==monsters[i].y)
monsters[i].dead=TRUE;
}
}
U0 Init()
{
I64 i,x,y,minx,maxx,miny,maxy;
CDC *dc;
SpriteExtents($IB,"<1>",BI=1$,&minx,&maxx,&miny,&maxy);
map_width =(maxx-minx+1)/MAP_SCALE;
map_height=(maxy-miny+1)/MAP_SCALE;
Free(map);
map=MAlloc(map_width*map_height*sizeof(U8));
dc=DCNew(map_width*MAP_SCALE,map_height*MAP_SCALE);
Sprite3(dc,-minx,-miny,0,$IB,"<1>",BI=1$);
for (y=0;y<map_height;y++)
for (x=0;x<map_width;x++)
map[y*map_width+x]=GrPeek(dc,x*MAP_SCALE,y*MAP_SCALE);
DCDel(dc);
for (i=0;i<NUM_MONSTERS;i++) {
monsters[i].dead=FALSE;
monsters[i].dx=0;
monsters[i].dy=0;
do {
monsters[i].x=RandU64%(map_width-2)+1;
monsters[i].y=RandU64%(map_height-2)+1;
} while (!map[(monsters[i].y)*map_width+monsters[i].x]);
}
man_attack_t0=tS;
man_attack=FALSE;
man_x=0;
man_y=4;
man_dx=0;
man_dy=0;
screen_x=0;
screen_y=0;
}
U0 CleanUp()
{
Free(map);
map=NULL;
}
U0 AnimateTask(I64)
{
I64 i,x,y,dx,dy;
while (TRUE) {
for (i=0;i<NUM_MONSTERS;i++)
if (!monsters[i].dead) {
dx=RandU16%3-1;
dy=RandU16%3-1;
x=monsters[i].x+dx;
y=monsters[i].y+dy;
if (0<=x<=map_width && 0<=y<=map_height &&
map[y*map_width+x]) {
monsters[i].x=x;
monsters[i].y=y;
monsters[i].dx=dx;
monsters[i].dy=dy;
}
}
Sleep(1000);
}
}
U0 DunGen()
{
I64 ch,sc;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" Up(,,SC_CURSOR_UP);"
" Down(,,SC_CURSOR_DOWN);"
" Left(,,SC_CURSOR_LEFT);"
" Right(,,SC_CURSOR_RIGHT);"
" Attack(,CH_SPACE);"
"}"
);
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
Fs->text_attr=BLACK<<4+WHITE;
Preempt(OFF);
WinMax;
WordStat;
Init;
Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
try {
while (TRUE) {
switch (GetMsg(&ch,&sc,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
case MSG_KEY_DOWN:
switch (ch) {
case '\n':
Init;
break;
case CH_SPACE:
man_attack=TRUE;
break;
case CH_ESC:
case CH_SHIFT_ESC:
goto dg_done;
case 0:
switch (sc.u8[0]) {
case SC_CURSOR_RIGHT:
if (man_attack) {
man_dx=1;
man_dy=0;
Attack;
} else
if (man_x+1<map_width && map[man_y*map_width+(man_x+1)]==RED) {
man_x++;
if (man_x-screen_x>SCREEN_WIDTH/2-3) {
screen_x+=SCREEN_WIDTH/2;
if (screen_x+SCREEN_WIDTH/2>map_width)
screen_x=map_width-SCREEN_WIDTH/2;
}
}
break;
case SC_CURSOR_LEFT:
if (man_attack) {
man_dx=-1;
man_dy=0;
Attack;
} else
if (man_x-1>=0 && map[man_y*map_width+(man_x-1)]==RED) {
man_x--;
if (man_x-screen_x<-SCREEN_WIDTH/2+3) {
screen_x-=SCREEN_WIDTH/2;
if (screen_x-SCREEN_WIDTH/2<0)
screen_x=SCREEN_WIDTH/2;
}
}
break;
case SC_CURSOR_UP:
if (man_attack) {
man_dx=0;
man_dy=-1;
Attack;
} else
if (man_y-1>=0 && map[(man_y-1)*map_width+man_x]==RED) {
man_y--;
if (man_y-screen_y<-SCREEN_HEIGHT/2+3) {
screen_y-=SCREEN_HEIGHT/2;
if (screen_y-SCREEN_HEIGHT/2<0)
screen_y=SCREEN_HEIGHT/2;
}
}
break;
case SC_CURSOR_DOWN:
if (man_attack) {
man_dx=0;
man_dy=1;
Attack;
} else
if (man_y+1<map_height && map[(man_y+1)*map_width+man_x]==RED) {
man_y++;
if (man_y-screen_y>SCREEN_HEIGHT/2-3) {
screen_y+=SCREEN_HEIGHT/2;
if (screen_y+SCREEN_HEIGHT/2>map_height)
screen_y=map_height-SCREEN_HEIGHT/2;
}
}
break;
}
}
break;
case MSG_KEY_UP:
if (ch==CH_SPACE)
man_attack=FALSE;
break;
}
}
dg_done:
GetMsg(,,1<<MSG_KEY_UP);
} catch
PutExcept;
SettingsPop;
MenuPop;
CleanUp;
}
DunGen;
£
|˜
˜øÿÿÿ˜
˜´
´´øÿÿÿ
´øÿÿÿ˜øÿÿÿ
¤¤
œ °
° °üÿÿÿ
°üÿÿÿœüÿÿÿ
œüÿÿÿœ
œ¬
¬¬
¬ 
  
 ¨
¤$Ì$
Ì$Ì@
Ì@¤@
¤@¤(
¨(È(
È(È<
È<¨<
¨<¨,
¨,Ä,
Ä,Ä8
Ä8¬8
¬8¬0
¬0À0
À0À4
À4°4
Ì4ä4
ä(ä@
ä@@
@
ø
øø$
ø$ä$
è(ü(
üü<
ø<è<
è8è,
è,ø,
ø,ø8
ø8ì<
ì8ì0
ì0ô0
ð4ô4
ô8ð8
üü
üì
èøÿÿÿè
èÔ
ÔÔøÿÿÿ
Ôøÿÿÿäøÿÿÿ
äøÿÿÿà
ä äüÿÿÿ
äüÿÿÿØüÿÿÿ
ØüÿÿÿØ
Ø Ü
Ü Ü
àà
ÐÌ
ÈüÿÿÿÈ
È Ä
Ä Äüÿÿÿ
 4�4
Œ,Œ<
Œ<€<
€<€,
€,ˆ,
ˆ,ˆ8
ˆ8„8
„8„0
˜4˜L
”LœL
œLœX
œX”X
”X”P
˜P˜T
¼ôÿÿÿ¼0
¼8¼P
¼P¼X°Ä,Ä8Rýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²%þÿÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJ$ýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2ýÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ   ÿÿÿÿÿÿÿÿÿÿÿÿ    ÿÿÿÿÿÿÿ   ÿÿÿ    ÿÿ      ÿÿÿ    ÿÿ   ÿÿ  ÿÿÿÿÿÿ      ÿÿÿÿÿÿÿÿÿÿ   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2ýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿ   ÿÿÿÿÿÿÿ     ÿÿÿ    ÿÿ    ÿÿÿ    ÿÿ    ÿÿ  ÿÿÿÿÿÿ       ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ' ìÿÿÿéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ␍ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ␍␍␍␍ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ␍␍␍␍␍␍ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ␍␍␍␍␍ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ␍␍␍ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
òþÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ b ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²'$ìÿÿÿäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿ ÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿ ÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²öÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
File diff suppressed because it is too large. Load diff
+774
View File
@@ -0,0 +1,774 @@
#define GAME_SPEED_SCALE 0.1
F64 game_speed,
launch_unit_x1,launch_unit_y1,launch_unit_x2,launch_unit_y2,launch_t,
return_unit_x1,return_unit_y1,return_unit_x2,return_unit_y2,return_t,
set_é_unit_x1,set_é_unit_y1,set_é_unit_x2,set_é_unit_y2,set_é_t;
CTask *main_task;
#define OT_CARRIER 0
#define OT_CRUISER 1
#define OT_FIGHTER 2
#define OT_NUM_TYPES 3
#define OF_SHIP 1
#define OF_ACTIVE 2
#define OF_RETURNING 4
#define OF_SHOOTING 8
class Obj
{
Obj *next,*last;
Obj *next_in_squadron,*last_in_squadron;
Obj *host;
U8 player,type;
U16 flags;
I16 squadron,member_num;
F64 x,y,é,dé,
speed,turn_rate,
life_percent,
target_x,target_y,
ship_guns,ship_guns_range,
air_guns,air_guns_range,
fuel,max_fuel,fuel_burn_rate,
death_time,next_action_time;
I32 torpedos,max_torpedos;
F64 torpedos_range;
} obj_root;
class Torpedo
{
Torpedo *next,*last;
Obj *target;
F64 x,y,é,speed,timeout;
} torpedo_root;
#define SA_PARKED 0
#define SA_LAUNCHING 1
#define SA_FLYING 2
#define SA_SET_é 3
#define SA_RETURNING 4
#define SA_DEAD 5
class Squadron : Obj
{
I64 action,dead_mask,total_mask;
} *squadrons;
U0 SquadronIns(Obj *o,Obj *pred)
{
Obj *succ=pred->next_in_squadron;
o->next_in_squadron=succ;
o->last_in_squadron=pred;
pred->next_in_squadron=o;
succ->last_in_squadron=o;
}
U0 SquadronRem(Obj *o)
{
Obj *pred=o->last_in_squadron,*succ=o->next_in_squadron;
pred->next_in_squadron=succ;
succ->last_in_squadron=pred;
}
#define NUM_PLAYERS 2
I64 num_carriers[NUM_PLAYERS]={2,3},
num_cruisers[NUM_PLAYERS]={2,3},
num_planes_per_squadron[NUM_PLAYERS]={6,5},
num_squadrons_per_carrier[NUM_PLAYERS]={2,3},
num_alive[NUM_PLAYERS],
num_squadrons;
Obj *ObjFind(F64 x,F64 y,
I64 flag_mask=OF_ACTIVE|OF_RETURNING,I64 flag_val=OF_ACTIVE,
I64 type_mask=-1,I64 player_mask=-1,F64 *_d=NULL)
{
Obj *tempo=obj_root.next,*best=NULL;
F64 dd,best_dd=MAX_F64;
while (tempo!=&obj_root) {
if (tempo->flags&flag_mask==flag_val &&
Bt(&type_mask,tempo->type)&&Bt(&player_mask,tempo->player)) {
dd=Sqr(tempo->x-x)+Sqr(tempo->y-y);
if (dd<best_dd) {
best=tempo;
best_dd=dd;
}
}
tempo=tempo->next;
}
if (_d) *_d=Sqrt(best_dd);
return best;
}
U0 ObjDel(Obj *tempo)
{
if (tempo) {
if (tS<tempo->death_time)
tempo->flags&=~OF_ACTIVE;
else {
if (tempo->squadron>=0)
SquadronRem(tempo);
QueRem(tempo);
if (tempo->squadron>=0)
LBts(&squadrons[tempo->squadron].dead_mask,tempo->member_num);
num_alive[tempo->player]--;
Free(tempo);
}
}
}
$BG,1$
$SP,"<1>",BI=1$
$SP,"<2>",BI=2$
$SP,"<3>",BI=3$
$SP,"<4>",BI=4$
$SP,"<5>",BI=5$
$SP,"<6>",BI=6$
$BG$
CSprite *imgs[NUM_PLAYERS][OT_NUM_TYPES]={{$IB,"<1>",BI=1$,$IB,"<2>",BI=2$,$IB,"<3>",BI=3$},{$IB,"<4>",BI=4$,$IB,"<5>",BI=5$,$IB,"<6>",BI=6$}};
U0 DrawIt(CTask *task,CDC *dc)
{
F64 d,cur_time=tS;
Obj *tempo;
Torpedo *tempt;
Bool old_preempt=Preempt(OFF);
tempt=torpedo_root.next;
while (tempt!=&torpedo_root) {
dc->color=WHITE;
GrPlot(dc,tempt->x,tempt->y);
tempt=tempt->next;
}
tempo=obj_root.next;
while (tempo!=&obj_root) {
if (tempo->flags&OF_ACTIVE && tempo->flags&OF_SHIP) {
SpriteZ3B(dc,tempo->x,tempo->y,0,imgs[tempo->player][tempo->type],tempo->é+ã/2);
if (Blink) {
dc->color=BLACK;
GrLine(dc,tempo->x+5,tempo->y,tempo->x+5+10,tempo->y);
if (tempo->life_percent>0) {
if (tempo->life_percent<33)
dc->color=RED;
else if (tempo->life_percent<66)
dc->color=YELLOW;
else
dc->color=GREEN;
GrLine(dc,tempo->x+5,tempo->y,tempo->x+5+10*tempo->life_percent/100,tempo->y);
}
dc->color=BLACK;
GrLine(dc,tempo->x+5,tempo->y+2,tempo->x+5+10,tempo->y+2);
d=tempo->fuel*100/tempo->max_fuel;
if (d>0) {
if (d<33)
dc->color=RED;
else if (d<66)
dc->color=YELLOW;
else
dc->color=GREEN;
GrLine(dc,tempo->x+5,tempo->y+2,tempo->x+5+10*d/100,tempo->y+2);
}
}
}
tempo=tempo->next;
}
tempo=obj_root.next;
while (tempo!=&obj_root) {
if (tempo->flags&OF_ACTIVE && !(tempo->flags&OF_SHIP))
SpriteZ3B(dc,tempo->x,tempo->y,0,imgs[tempo->player][tempo->type],tempo->é+ã/2);
if (tempo->flags&OF_SHOOTING) {
dc->color=LTRED;
GrLine(dc,tempo->x,tempo->y,tempo->target_x,tempo->target_y,3);
}
tempo=tempo->next;
}
dc->flags|=DCF_TRANSFORMATION;
if (cur_time<launch_t) {
dc->color=LTGREEN;
GrArrow3(dc,launch_unit_x1,launch_unit_y1,0,launch_unit_x2,launch_unit_y2,0);
}
if (cur_time<return_t) {
dc->color=LTRED;
GrArrow3(dc,return_unit_x1,return_unit_y1,0,return_unit_x2,return_unit_y2,0);
}
if (cur_time<set_é_t) {
dc->color=YELLOW;
GrArrow3(dc,set_é_unit_x1,set_é_unit_y1,0,set_é_unit_x2,set_é_unit_y2,0);
}
dc->color=YELLOW;
GrPrint(dc,-task->scroll_x,-task->scroll_y,"Game Speed: %5.2f",game_speed);
dc->color=LTCYAN;
GrPrint(dc,-task->scroll_x,-task->scroll_y+ FONT_HEIGHT,"Player 1: %d",num_alive[0]);
dc->color=LTPURPLE;
GrPrint(dc,-task->scroll_x,-task->scroll_y+2*FONT_HEIGHT,"Player 2: %d",num_alive[1]);
if ((!num_alive[0]||!num_alive[1]) && Blink) {
if (!num_alive[1]) {
dc->color=LTGREEN;
GrPrint(dc,task->pix_width>>1 -(FONT_WIDTH*14)/2-task->scroll_x,
task->pix_height>>1-FONT_HEIGHT/2-task->scroll_y,"Game Completed");
} else {
dc->color=LTRED;
GrPrint(dc,task->pix_width>>1 -(FONT_WIDTH*9)/2-task->scroll_x,
task->pix_height>>1-FONT_HEIGHT/2-task->scroll_y,"Game Over");
}
}
Preempt(old_preempt);
}
U0 Init()
{
I64 i,fighter,ship,player,squadron,
w=Fs->pix_width,h=Fs->pix_height;
Squadron *temps;
Obj *tempo,*tempo1;
QueInit(&obj_root);
QueInit(&torpedo_root);
Fs->scroll_x=0;
Fs->scroll_y=0;
game_speed=1.0;
launch_t=return_t=set_é_t=0;
main_task=Fs;
num_squadrons=0;
for (player=0;player<NUM_PLAYERS;player++) {
num_alive[player]=0;
for (ship=0;ship<num_cruisers[player];ship++) {
tempo1=CAlloc(sizeof(Obj));
num_alive[player]++;
tempo1->type=OT_CRUISER; tempo1->player=player;
tempo1->squadron=-1; tempo1->member_num=ship;
tempo1->flags=OF_ACTIVE|OF_SHIP;
tempo1->x=0.8*w*(Rand-0.5)+w>>1; tempo1->y=0.8*h*(Rand-0.5)+h>>1;
tempo1->host=NULL;
tempo1->speed=35.0; tempo1->turn_rate=2.5;
tempo1->é=2*ã*(Rand-0.5); tempo1->dé=0;
tempo1->life_percent=100.0;
tempo1->fuel=tempo1->max_fuel=100000;
tempo1->fuel_burn_rate=100.0;
tempo1->air_guns =5000; tempo1->air_guns_range =30.0;
tempo1->ship_guns=10000; tempo1->ship_guns_range=30.0;
tempo1->torpedos =tempo1->max_torpedos=0;
tempo1->torpedos_range =0.0;
tempo1->next_action_time=0;
QueIns(tempo1,obj_root.last);
}
for (ship=0;ship<num_carriers[player];ship++) {
tempo1=CAlloc(sizeof(Obj));
num_alive[player]++;
tempo1->type=OT_CARRIER; tempo1->player=player;
tempo1->squadron=-1; tempo1->member_num=ship;
tempo1->flags=OF_ACTIVE|OF_SHIP;
tempo1->x=0.8*w*(Rand-0.5)+w>>1; tempo1->y=0.8*h*(Rand-0.5)+h>>1;
tempo1->host=NULL;
tempo1->speed=28.0; tempo1->turn_rate=1.0;
tempo1->é=2*ã*(Rand-0.5); tempo1->dé=0;
tempo1->life_percent=100.0;
tempo1->fuel=tempo1->max_fuel=750000;
tempo1->fuel_burn_rate=500.0;
tempo1->air_guns =5000; tempo1->air_guns_range =20.0;
tempo1->ship_guns=2000; tempo1->ship_guns_range=30.0;
tempo1->torpedos =tempo1->max_torpedos=0;
tempo1->torpedos_range =0.0;
tempo1->next_action_time=0;
QueIns(tempo1,obj_root.last);
for (squadron=0;squadron<num_squadrons_per_carrier[player];squadron++,num_squadrons++) {
for (fighter=0;fighter<num_planes_per_squadron[player];fighter++) {
tempo=CAlloc(sizeof(Obj));
num_alive[player]++;
tempo->type=OT_FIGHTER; tempo->player=player;
tempo->squadron=num_squadrons; tempo->member_num=fighter;
tempo->flags=0;
tempo->host=tempo1;
tempo->speed=300.0; tempo->turn_rate=25.0;
tempo->life_percent=100.0;
tempo->fuel=tempo->max_fuel=1000;
tempo->fuel_burn_rate=1.0;
tempo->air_guns =35000; tempo->air_guns_range =8.0;
tempo->ship_guns=0; tempo->ship_guns_range=0.0;
tempo->torpedos =tempo->max_torpedos=1;
tempo->torpedos_range =20.0;
QueIns(tempo,obj_root.last);
}
}
}
}
squadrons=CAlloc(num_squadrons*sizeof(Squadron));
for (i=0,temps=squadrons;i<num_squadrons;i++,temps++) {
temps->next_in_squadron=temps->last_in_squadron=temps;
temps->squadron=i;
}
tempo=obj_root.next;
while (tempo!=&obj_root) {
if (tempo->squadron>=0) {
temps=&squadrons[tempo->squadron];
temps->host =tempo->host;
temps->player=tempo->player;
temps->total_mask=1<<num_planes_per_squadron[tempo->player]-1;
SquadronIns(tempo,temps->last_in_squadron);
}
tempo=tempo->next;
}
}
U0 CleanUp()
{
QueDel(&obj_root,TRUE);
QueDel(&torpedo_root,TRUE);
Free(squadrons);
}
Obj *ObjLaunch(I64 player,I64 squadron=-1,Obj *host=NULL,F64 x=MAX_F64,F64 y=MAX_F64,F64 é=MAX_F64)
{
Obj *tempo;
F64 cur_time=tS;
if (!host)
host=ObjFind(x,y,,,1<<OT_CARRIER,1<<player);
if (host && cur_time>host->next_action_time) {
if (é==MAX_F64)
é=Arg(x-host->x,y-host->y);
tempo=obj_root.next;
while (tempo!=&obj_root) {
if (tempo->host==host && (squadron<0||tempo->squadron==squadron) && !(tempo->flags&OF_ACTIVE) &&
(tempo->squadron<0||squadrons[tempo->squadron].action==SA_PARKED||squadrons[tempo->squadron].action==SA_LAUNCHING)) {
if (tempo->fuel<=0.0) //When low on fuel, not zero, gets launched and captured.
LBts(&squadrons[tempo->squadron].dead_mask,tempo->member_num);
else {
tempo->flags=tempo->flags&~OF_RETURNING|OF_ACTIVE;
tempo->é=host->é;
if (x==MAX_F64 || y==MAX_F64 || Sqr(x-host->x)+Sqr(y-host->y)>3*3)
tempo->dé=Wrap(é-tempo->é,-ã);
else
tempo->dé=0;
tempo->x=host->x;
tempo->y=host->y;
host->next_action_time=cur_time+0.25/game_speed;
return tempo;
}
}
tempo=tempo->next;
}
}
return NULL;
}
Squadron *SquadronLaunch(I64 player,F64 x=MAX_F64,F64 y=MAX_F64)
{
Squadron *temps;
Obj *tempo;
if (tempo=ObjLaunch(player,,,x,y)) {
if (player==0) {
launch_unit_x1=tempo->x;
launch_unit_y1=tempo->y;
launch_unit_x2=ipx-main_task->pix_left-main_task->scroll_x;
launch_unit_y2=ipy-main_task->pix_top -main_task->scroll_y;
launch_t=tS+0.5;
}
if (tempo->squadron>=0) {
temps=&squadrons[tempo->squadron];
if (temps->action==SA_PARKED) {
temps->action=SA_LAUNCHING;
temps->é=tempo->é+tempo->dé;
}
return temps;
}
}
return NULL;
}
Obj *ObjReturn(I64 player,F64 x,F64 y)
{
Obj *tempo;
if (tempo=ObjFind(x,y,OF_ACTIVE,OF_ACTIVE,1<<OT_FIGHTER,1<<player))
tempo->flags|=OF_RETURNING;
return tempo;
}
Squadron *SquadronReturn(I64 player,F64 x,F64 y)
{
Squadron *temps;
Obj *tempo;
if (tempo=ObjReturn(player,x,y)) {
if (player==0) {
return_unit_x1=tempo->x;
return_unit_y1=tempo->y;
if (tempo->host) {
return_unit_x2=tempo->host->x;
return_unit_y2=tempo->host->y;
return_t=tS+0.5;
}
}
if (tempo->squadron>=0) {
temps=&squadrons[tempo->squadron];
if (temps->action==SA_FLYING)
temps->action=SA_RETURNING;
return temps;
}
}
return NULL;
}
Obj *ObjSeté(I64 player,F64 x=MAX_F64,F64 y=MAX_F64,F64 é=MAX_F64)
{
Obj *tempo;
if ((tempo=ObjFind(x,y,,,,1<<player)) && tempo->flags&OF_ACTIVE && !(tempo->flags&OF_RETURNING)) {
if (é==MAX_F64)
é=Arg(x-tempo->x,y-tempo->y);
tempo->dé+=Wrap(é-(tempo->é+tempo->dé),-ã);
return tempo;
}
return NULL;
}
Squadron *SquadronSeté(I64 player,F64 x=MAX_F64,F64 y=MAX_F64,F64 é=MAX_F64)
{
Squadron *temps;
Obj *tempo;
if (tempo=ObjSeté(player,x,y,é)) {
if (player==0) {
set_é_unit_x1=tempo->x;
set_é_unit_y1=tempo->y;
set_é_unit_x2=ipx-main_task->pix_left-main_task->scroll_x;
set_é_unit_y2=ipy-main_task->pix_top -main_task->scroll_y;
set_é_t=tS+0.5;
}
if (tempo->squadron>=0) {
temps=&squadrons[tempo->squadron];
if (temps->action==SA_FLYING) {
temps->action=SA_SET_é;
temps->é=tempo->é+tempo->dé;
}
return temps;
}
}
return NULL;
}
U0 SquadronActions()
{
I64 i,completed_mask;
Obj *tempo;
Squadron *temps;
for (i=0,temps=squadrons;i<num_squadrons;i++,temps++) {
completed_mask=0;
switch (temps->action) {
case SA_LAUNCHING:
ObjLaunch(temps->player,i,temps->host,,,temps->é);
tempo=temps->next_in_squadron;
while (tempo!=temps) {
LBEqu(&completed_mask,tempo->member_num,tempo->flags&OF_ACTIVE);
tempo=tempo->next_in_squadron;
}
if (completed_mask|temps->dead_mask==temps->total_mask)
temps->action=SA_FLYING;
break;
case SA_FLYING:
tempo=temps->next_in_squadron;
while (tempo!=temps) {
LBEqu(&completed_mask,tempo->member_num,!(tempo->flags&OF_ACTIVE));
tempo=tempo->next_in_squadron;
}
if (completed_mask|temps->dead_mask==temps->total_mask)
temps->action=SA_PARKED;
break;
case SA_SET_é:
tempo=temps->next_in_squadron;
while (tempo!=temps) {
tempo->dé+=Wrap(temps->é-(tempo->é+tempo->dé),-ã);
tempo=tempo->next_in_squadron;
}
temps->action=SA_FLYING;
break;
case SA_RETURNING:
tempo=temps->next_in_squadron;
while (tempo!=temps) {
tempo->flags|=OF_RETURNING;
LBEqu(&completed_mask,tempo->member_num,!(tempo->flags&OF_ACTIVE));
tempo=tempo->next_in_squadron;
}
if (completed_mask|temps->dead_mask==temps->total_mask)
temps->action=SA_PARKED;
break;
}
if (temps->dead_mask==temps->total_mask)
temps->action=SA_DEAD;
}
}
U0 AI(I64 player,F64 period)
{
Obj *tempo;
tempo=obj_root.next;
while (tempo!=&obj_root) {
if (tempo->player==player) {
if (tempo->type==OT_CARRIER && Rand<5*period)
SquadronLaunch(player,tempo->x,tempo->y);
if (tempo->flags&OF_ACTIVE && !(tempo->flags&OF_RETURNING) && Rand<10.0*period)
SquadronSeté(player,tempo->x,tempo->y,tempo->é+pi/2*(Rand-0.5));
}
tempo=tempo->next;
}
}
U0 Combat(F64 period)
{
F64 d;
Obj *tempo,*tempo1;
Torpedo *tempt;
tempo=obj_root.next;
while (tempo!=&obj_root) {
tempo->flags&=~OF_SHOOTING;
if (tempo->flags&OF_ACTIVE &&
(tempo1=ObjFind(tempo->x,tempo->y,OF_ACTIVE,OF_ACTIVE,,1<<(tempo->player^1),&d))) {
tempo->target_x=tempo1->x;
tempo->target_y=tempo1->y;
if (tempo1->flags&OF_SHIP) {
if (tempo->torpedos && d<tempo->torpedos_range && Rand<125*period) {
tempo->torpedos--;
tempt=CAlloc(sizeof(Torpedo));
tempt->x=tempo->x;
tempt->y=tempo->y;
tempt->speed=100;
d/=tempt->speed*(GAME_SPEED_SCALE*game_speed);
tempo1->death_time=tempt->timeout=tS+d;
tempt->target=tempo1;
tempt->é=Arg(tempo1->x-tempo->x,tempo1->y-tempo->y);
QueIns(tempt,torpedo_root.last);
Sweep(2000,2000,300);
} else if (tempo->ship_guns>0 && d<tempo->ship_guns_range) {
tempo->flags|=OF_SHOOTING;
if (Rand<125.0*period) {
tempo1->life_percent-=tempo->ship_guns*Rand*period;
if (Rand<10.0*period)
tempo1->fuel*=0.75*Rand+0.25;
}
Noise(100,75,200);
}
} else {
if (tempo->air_guns>0 && d<tempo->air_guns_range) {
tempo->flags|=OF_SHOOTING;
if (Rand<125.0*period) {
tempo1->life_percent-=tempo->air_guns*Rand*period;
if (Rand<10.0*period)
tempo1->fuel*=0.75*Rand+0.25;
}
Noise(25,500,2000);
}
}
}
tempo=tempo->next;
}
tempo=obj_root.next;
while (tempo!=&obj_root) {
tempo1=tempo->next;
if (tempo->type==OT_FIGHTER &&
(tempo->life_percent<=0.0 || tempo->flags&OF_ACTIVE && tempo->fuel<=0.0 ||
tempo->host && !(tempo->flags&OF_ACTIVE) && tempo->host->life_percent<=0.0))
ObjDel(tempo);
tempo=tempo1;
}
tempo=obj_root.next;
while (tempo!=&obj_root) {
tempo1=tempo->next;
if (tempo->life_percent<=0.0)
ObjDel(tempo);
tempo=tempo1;
}
}
#define ANIMATE_FREQ 50
U0 AnimateTask(I64)
{ //Preemption is off after Spawn
Obj *tempo;
Torpedo *tempt,*tempt1;
F64 d,period;
I64 cnt=0;
while (TRUE) {
period=GAME_SPEED_SCALE*game_speed/ANIMATE_FREQ;
SquadronActions;
tempo=obj_root.next;
while (tempo!=&obj_root) {
if (tempo->flags&OF_ACTIVE && tempo->fuel>0) {
if (tempo->dé) {
d=tempo->dé;
if (d> tempo->turn_rate*period) d= tempo->turn_rate*period;
if (d<-tempo->turn_rate*period) d=-tempo->turn_rate*period;
tempo->é +=d;
tempo->dé-=d;
}
tempo->x+=tempo->speed*Cos(tempo->é)*period*tempo->life_percent/100.0;
tempo->y+=tempo->speed*Sin(tempo->é)*period*tempo->life_percent/100.0;
tempo->fuel-=tempo->speed*tempo->fuel_burn_rate*period;
}
tempo=tempo->next;
}
tempt=torpedo_root.next;
while (tempt!=&torpedo_root) {
tempt1=tempt->next;
if (tS>tempt->timeout) {
tempo=tempt->target;
if (Rand<0.333333) {
tempo->life_percent-=150*Rand*Rand;
if (Rand<0.333333)
tempo->fuel*=0.75*Rand+0.25;
}
QueRem(tempt);
Free(tempt);
} else {
tempt->x+=tempt->speed*Cos(tempt->é)*period;
tempt->y+=tempt->speed*Sin(tempt->é)*period;
}
tempt=tempt1;
}
tempo=obj_root.next;
while (tempo!=&obj_root) {
if (tempo->host && !(tempo->flags&OF_ACTIVE)) {
tempo->x=tempo->host->x;
tempo->y=tempo->host->y;
}
tempo=tempo->next;
}
tempo=obj_root.next;
while (tempo!=&obj_root) {
if (tempo->flags&OF_ACTIVE) {
if (tempo->host) {
d=Sqrt(Sqr(tempo->x-tempo->host->x)+Sqr(tempo->y-tempo->host->y));
if (d<8 && tempo->max_fuel-tempo->fuel>30) {
tempo->life_percent=100.0;
if (tempo->host->fuel>0) {
d=tempo->max_fuel-tempo->fuel;
if (d>tempo->host->fuel) d=tempo->host->fuel;
tempo->host->fuel-=d;
tempo->fuel+=d;
}
tempo->torpedos=tempo->max_torpedos;
tempo->x=tempo->host->x;
tempo->y=tempo->host->y;
tempo->flags&=~OF_ACTIVE;
} else if (d>tempo->fuel-250)
tempo->flags|=OF_RETURNING;
if (tempo->flags&OF_RETURNING)
tempo->dé+=Wrap(Arg(tempo->host->x-tempo->x,tempo->host->y-tempo->y)-(tempo->é+tempo->dé),-ã);
} else if (tempo->type==OT_CARRIER)
tempo->life_percent=Min(100.0,tempo->life_percent+2.5*period);
}
tempo=tempo->next;
}
AI(1,period);
Combat(period);
Sleep(1000/ANIMATE_FREQ);
}
}
U0 FlatTops()
{
I64 p1,p2;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
Fs->text_attr=BLUE<<4+WHITE;
PopUpOk("$$GREEN$${Left-Mouse}$$FG$$\t\tChange Course\n"
"$$GREEN$${Right-Mouse}$$FG$$\t\tLaunch Squadron\n"
"$$GREEN$${Right-Double-Mouse}$$FG$$\tReturn Squadron\n"
"$$GREEN$${Ctrl-Left Grab}$$FG$$\tScroll Screen\n");
Preempt(OFF),
WinBorder;
WordStat;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" Faster(,'+');"
" Slower(,'-');"
"}"
);
WinMax;
Fs->win_inhibit|=WIF_IP_L|WIF_IP_R;
Init;
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
try {
while (TRUE)
switch(GetMsg(&p1,&p2,1<<MSG_KEY_DOWN|1<<MSG_IP_L_UP|1<<MSG_IP_R_UP|1<<MSG_IP_R_D_UP)) {
case MSG_KEY_DOWN:
switch (p1) {
case '\n':
CleanUp;
Init;
break;
case CH_ESC:
case CH_SHIFT_ESC:
goto nv_done;
case '+':
game_speed*=1.5;
break;
case '-':
game_speed/=1.5;
break;
}
break;
case MSG_IP_L_UP:
SquadronSeté(0,p1,p2);
break;
case MSG_IP_R_UP:
SquadronLaunch(0,p1,p2);
break;
case MSG_IP_R_D_UP:
SquadronReturn(0,p1,p2);
break;
}
nv_done:
GetMsg(,,1<<MSG_KEY_UP);
} catch
PutExcept;
MenuPop;
SettingsPop;
CleanUp;
}
FlatTops;
r&úÿÿÿéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿ ÿ ÿ ÿ ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿr&úÿÿÿéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ␍␍␍ÿ␍␍ÿ␍␍ÿ␍␍ÿ␍␍ÿ␍ÿ␍ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿb %üÿÿÿìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿ ÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿb %üÿÿÿìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ␍␍ÿÿÿ␍␍ÿÿÿÿ␍␍␍␍ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0
þÿÿÿ
ÿÿÿÿ 0
þÿÿÿ
ÿÿÿÿ␍
+165
View File
@@ -0,0 +1,165 @@
#define NUM_ROAD 512
#define ROAD_WIDTH_BY_2 200
#define CAR_WIDTH_BY_2 100
I64 road_x[NUM_ROAD],road_trend;
F64 speed,distance;
I64 road_ptr=0,car_x;
F64 t_last;
Bool crash;
U0 DrawIt(CTask *task,CDC *dc)
{
I64 w=task->pix_width,h=task->pix_height;
I64 i,x,y,xx;
Bool old_preempt=Preempt(OFF);
xx=w>>1-car_x+road_x[road_ptr&(NUM_ROAD-1)];
dc->color=LTGRAY;
for (i=0;i<NUM_ROAD;i++) {
x=w>>1-car_x+road_x[(i+road_ptr)&(NUM_ROAD-1)];
y=h-0.5*i;
if (y<(h+FONT_HEIGHT)>>1) break;
GrPlot(dc,x+ROAD_WIDTH_BY_2-0.4*i,y);
GrPlot(dc,x-ROAD_WIDTH_BY_2+0.4*i,y);
}
dc->color=WHITE;
x=w>>1-CAR_WIDTH_BY_2;
if (x<xx-ROAD_WIDTH_BY_2)
crash=TRUE;
GrLine(dc,x-10,h,x-40,h-100);
GrLine(dc,x+10,h,x+40,h-100);
x=w>>1+CAR_WIDTH_BY_2;
if (x>xx+ROAD_WIDTH_BY_2)
crash=TRUE;
GrLine(dc,x-10,h,x-40,h-100);
GrLine(dc,x+10,h,x+40,h-100);
dc->color=YELLOW;
if (crash)
GrPrint(dc,w>>1-FONT_WIDTH*4,(h-FONT_HEIGHT)>>1,"Game Over");
Preempt(old_preempt);
}
U0 UpdateRoad()
{
F64 t0=tS;
distance+=speed*(t0-t_last);
t_last=t0;
while (distance>1.0) {
road_trend=ClampI64(road_trend+SignI64(RandU16%3-1),-5,5);
road_x[road_ptr&(NUM_ROAD-1)]=
road_x[(road_ptr-1)&(NUM_ROAD-1)]+=road_trend/3;
road_ptr++;
distance-=1.0;
}
}
U0 Init()
{
I64 i,x=0;
DocClear;
"$$BG,DKGRAY$$"; NewLine((TEXT_ROWS-1)/2);
speed=0;
distance=0;
road_trend=0;
road_ptr=0;
car_x=0;
for (i=0;i<NUM_ROAD;i++) {
road_x[i]=x;
road_trend=ClampI64(road_trend+SignI64(RandU16%3-1),-5,5);
x+=road_trend/3;
}
t_last=tS;
crash=FALSE;
}
U0 Halogen()
{
I64 p1,p2,ch=0,sc=0;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
Fs->text_attr=BLACK<<4+WHITE;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" Accelerate(,,SC_CURSOR_UP);"
" Deccellerate(,,SC_CURSOR_DOWN);"
" Left(,,SC_CURSOR_LEFT);"
" Right(,,SC_CURSOR_RIGHT);"
"}"
);
Preempt(OFF);
WordStat;
WinMax;
Init;
DocCursor;
Fs->draw_it=&DrawIt;
try {
while (TRUE) {
switch (ScanMsg(&p1,&p2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
case MSG_KEY_DOWN:
ch=p1;sc=p2;
switch (ch) {
case '\n':
Init;
break;
case CH_ESC:
case CH_SHIFT_ESC:
goto ha_done;
}
break;
case MSG_KEY_UP:
ch=p1;sc=p2;
if (!ch)
switch (sc.u8[0]) {
case SC_CURSOR_RIGHT:
case SC_CURSOR_LEFT:
case SC_CURSOR_UP:
case SC_CURSOR_DOWN:
sc=0;
break;
}
break;
}
switch (sc.u8[0]) {
case SC_CURSOR_RIGHT:
car_x++;
break;
case SC_CURSOR_LEFT:
car_x--;
break;
case SC_CURSOR_UP:
if (++speed>200) speed=200;
break;
case SC_CURSOR_DOWN:
if (--speed<0) speed=0;
break;
}
if (crash)
Snd(0);
else {
if (speed)
Snd(speed+10);
else
Snd(0);
UpdateRoad;
}
Sleep(10);
}
ha_done:
GetMsg(,,1<<MSG_KEY_UP);
} catch
PutExcept;
MenuPop;
DocClear;
SettingsPop;
}
Halogen;
+189
View File
@@ -0,0 +1,189 @@
class MyMass:CMass
{
F64 radius;
};
class MySpring:CSpring
{
};
CMathODE *ode=NULL;
U0 DrawIt(CTask *task,CDC *dc)
{
Bool old_suspend;
MyMass *tempm;
MySpring *temps;
old_suspend=Suspend(task);
dc->color=RED;
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
GrLine(dc,temps->end1->x,temps->end1->y,
temps->end2->x,temps->end2->y);
temps=temps->next;
}
dc->color=BLACK;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
GrCircle(dc,tempm->x,tempm->y,tempm->radius);
tempm=tempm->next;
}
Suspend(task,old_suspend);
}
U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
{
//The forces due to springs and drag are
//automatically handled by the
//ode code. We can add new forces
//here.
F64 d,dd;
CD3 p;
MyMass *tempm1,*tempm2;
tempm1=ode->next_mass;
while (tempm1!=&ode->next_mass) {
tempm2=tempm1->next;
while (tempm2!=&ode->next_mass) {
D3Sub(&tempm2->state->x,&tempm1->state->x,&p);
dd=D3SqrNorm(&p);
if (dd<=Sqr(tempm1->radius+tempm2->radius)) {
d=Sqrt(dd)+0.0001;
dd=10.0*Sqr(Sqr(Sqr(tempm1->radius+tempm2->radius)-dd));
D3MulEqu(&p,dd/d);
D3AddEqu(&tempm2->DstateDt->DxDt,&p);
D3SubEqu(&tempm1->DstateDt->DxDt,&p);
}
tempm2=tempm2->next;
}
tempm1=tempm1->next;
}
}
U0 PlaceMass(I64 x, I64 y)
{
MyMass *tempm=CAlloc(sizeof(MyMass));
tempm->mass=1.0;
tempm->drag_profile_factor=100.0;
tempm->x=x;
tempm->y=y;
tempm->radius=10*(Rand+0.25);
QueIns(tempm,ode->last_mass);
}
U0 PlaceSpring(MyMass *tempm1,MyMass *tempm2)
{
MySpring *temps=CAlloc(sizeof(MySpring));
temps->end1=tempm1;
temps->end2=tempm2;
temps->const=10000;
temps->rest_len=100;
QueIns(temps,ode->last_spring);
}
U0 Init()
{
ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
ode->derivative=&MyDerivative;
ode->drag_v2=0.002;
ode->drag_v3=0.00001;
ode->acceleration_limit=5e3;
QueIns(ode,Fs->last_ode);
}
U0 CleanUp()
{
QueRem(ode);
QueDel(&ode->next_mass,TRUE);
QueDel(&ode->next_spring,TRUE);
ODEDel(ode);
}
U0 MassSpringDemo()
{
I64 msg_code,p1,p2;
MyMass *tempm1=NULL,*tempm2=NULL;
PopUpOk("Left-Click to place mas\n"
"Right-Click and drag to\n"
"connect with spring.\n\n"
"Springs are 100 pixs long.\n");
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
WinMax;
//This Preempt() eliminates a lot of hassles.
//The concern is about changing
//que links while the winmgr task
//is updating the ode or screen.
//The Window mgr suspends this
//task while updating the ode. It
//will not be interrupted and with this
//preempt, we will not be interrupted.
//There is little downside to Preempt()
//since we will yield during GetMsg().
Preempt(OFF);
Fs->win_inhibit|=WIG_DBL_CLICK;
WordStat;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
"}"
);
Init;
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
try {
while (TRUE) {
msg_code=GetMsg(&p1,&p2,1<<MSG_IP_L_DOWN|1<<MSG_IP_R_DOWN|1<<MSG_IP_R_UP|1<<MSG_KEY_DOWN);
switch (msg_code) {
case MSG_IP_L_DOWN:
PlaceMass(p1,p2);
break;
case MSG_IP_R_DOWN:
tempm1=MassFind(ode,p1,p2);
tempm2=NULL;
break;
case MSG_IP_R_UP:
if (tempm1 && (tempm2=MassFind(ode,p1,p2)) && tempm1!=tempm2)
PlaceSpring(tempm1,tempm2);
tempm1=tempm2=NULL;
break;
case MSG_KEY_DOWN:
switch (p1) {
case '\n':
CleanUp;
Init;
break;
case CH_SHIFT_ESC:
case CH_ESC:
goto ms_done;
}
break;
}
}
ms_done: //Don't goto out of try
GetMsg(,,1<<MSG_KEY_UP);
} catch
PutExcept;
SettingsPop;
CleanUp;
MenuPop;
}
MassSpringDemo;
+112
View File
@@ -0,0 +1,112 @@
//See $LK,"ExtScreenCodes",A="FA:::/Adam/Gr/GrScreen.CPP,ExtScreenCodes"$
#define ATTR (BLACK<<12+WHITE<<8)
U32 text[TEXT_ROWS][TEXT_COLS];
U0 DrawIt(CTask *task,CDC *)
{
MemCpy(gr_text_base+TEXT_COLS,text,(TEXT_ROWS-1)*TEXT_COLS*sizeof(U32));
// You can copy it this way, if you like:
// I64 i,j;
// for (j=0;j<TEXT_ROWS;j++)
// for (i=0;i<TEXT_COLS;i++)
// PlotWinU8(task,text[j][i],i,j);
PlotWinStr(task,"Draw a maze with left button.",ATTR>>8,0,0);
PlotWinStr(task,"Solve maze starting at right click.",ATTR>>8,0,1);
}
#define STK_SIZE 2048
//We would put these as local vars
//In SolveMaze() except the system stk size
//is limited. The heap is the normal TempleOS
//technique, but it's a pain in this case.
I64 stk_ptr,
stk_x [STK_SIZE],
stk_y [STK_SIZE],
stk_dir[STK_SIZE];
//Four directions:
// 0=Up,1=right,2=down,3=left
I64 dir_x[4]={ 0,+1, 0,-1}, // Could use $LK,"gr_x_offsets2",A="MN:gr_x_offsets2"$,$LK,"gr_y_offsets2",A="MN:gr_y_offsets2"$
dir_y[4]={+1, 0,-1, 0};
U0 SolveMaze(I64 x,I64 y)
{
I64 dir=0;
stk_ptr=0;
stk_x[stk_ptr]=x;
stk_y[stk_ptr]=y;
stk_dir[stk_ptr++]=dir;
while (TRUE) {
if (!(0<=x<MinI64(Fs->win_width,TEXT_COLS)) ||
!(0<=y<MinI64(Fs->win_height,TEXT_ROWS)) ) {
Beep;Beep;
break;
}
if (!text[y][x].u8[0])
text[y][x]='.'+ATTR;
x+=dir_x[dir];
y+=dir_y[dir];
//u8.[0] is the ASCII
if (text[y][x].u8[0]) {
x-=dir_x[dir];
y-=dir_y[dir];
if (++dir==4) {
if (--stk_ptr<0) return;
x=stk_x[stk_ptr];
y=stk_y[stk_ptr];
dir=stk_dir[stk_ptr];
}
} else {
dir=0;
stk_x[stk_ptr]=x;
stk_y[stk_ptr]=y;
stk_dir[stk_ptr++]=dir;
if (stk_ptr==STK_SIZE) return;
Sleep(100);
if (ScanChar)
ThrowBreak; //CTRL-ALT-C
}
}
}
U0 Maze()
{
I64 ch,x,y;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
WinMax;
WinBorder;
WordStat;
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
Fs->win_inhibit=WIG_TASK_DFT-WIF_FOCUS-WIF_BORDER;
try
do {
MemSet(text,0,sizeof(text));
while (!(ch=ScanChar)) {
//Input Ptr (mouse) text x,y coordinates.
x=iptx-Fs->win_left-Fs->scroll_x/FONT_WIDTH;
y=ipty-Fs->win_top-Fs->scroll_y/FONT_HEIGHT;
if (ip_lb&&!win_grab_scroll)
text[y][x]=CH_SPACE+ATTRF_INVERT+ATTR;
if (ip_rb&&!win_grab_scroll) {
text[y][x]='*'+ATTR;
SolveMaze(x,y);
ch=GetChar;
break;
}
WinMgrSync;
}
} while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
catch
PutExcept;
SettingsPop;
}
Maze;
+192
View File
@@ -0,0 +1,192 @@
I64 sc_1,sc_2;
#define NUM_DROPS 0x2000
class Drop
{
I32 x,y;
} drops[NUM_DROPS];
CDC *cur_dc;
U0 DrawFrame(CTask *task,CDC *dc)
{
I64 w=task->pix_width,h=task->pix_height,
cx=w>>1,cy=h>>1;
dc->color=LTRED;
GrLine(dc,cx-20,cy-50,cx,cy-150);
GrLine(dc,cx+20,cy-50,cx,cy-150);
dc->color=LTRED;
GrLine(dc,cx-100,cy-100,cx,cy);
GrLine(dc,cx+100,cy-100,cx,cy);
if (Bt(key_down_bitmap,sc_1)) {
dc->color=WHITE;
GrRect(dc,cx-2,cy-2,5,5);
}
dc->color=BLACK;
GrPrint(dc,cx+10,cy,"Press '1'");
dc->color=LTRED;
GrRect(dc,cx-20,cy+60,41,21);
dc->color=LTRED;
GrLine(dc,cx-200,cy,cx,cy+100);
GrLine(dc,cx+200,cy,cx,cy+100);
if (Bt(key_down_bitmap,sc_2)) {
dc->color=WHITE;
GrRect(dc,cx-2,cy+100-2,5,5);
}
dc->color=BLACK;
GrPrint(dc,cx+10,cy+100,"Press '2'");
dc->color=LTRED;
GrLine(dc,cx+400,cy+100,cx-250,cy+200);
}
U0 DrawDrops(CTask *,CDC *dc)
{
I64 i;
dc->color=BLUE;
for (i=0;i<NUM_DROPS;i++)
if (drops[i].y>=0 && GrPeek(dc,drops[i].x,drops[i].y)==WHITE)
GrPlot(dc,drops[i].x,drops[i].y);
}
U0 UpdateCurBase(CTask *task,CDC *dc)
{
Bool old_preempt=Preempt(OFF);
cur_dc->color=ROP_EQU;
dc->flags|=DCF_NO_TRANSPARENTS;
GrBlot(cur_dc,-task->pix_left-task->scroll_x,-task->pix_top-task->scroll_y,dc);
dc->flags&=~DCF_NO_TRANSPARENTS;
Preempt(old_preempt);
}
U0 DrawIt(CTask *task,CDC *dc)
{
DrawFrame(task,dc);
DrawDrops(task,dc);
UpdateCurBase(task,dc);
}
U0 AnimateTask(I64)
{
I64 i,j,cur_drop=0,c1,c2,x0,y0,x1,y1,w,h;
while (TRUE) {
w=Fs->parent_task->pix_width;
h=Fs->parent_task->pix_height;
for (i=0;i<2;i++) {
j=0;
do {
if (++cur_drop>=NUM_DROPS)
cur_drop=0;
if (drops[cur_drop].y<0)
break;
j++;
} while (j<=NUM_DROPS);
drops[cur_drop].x=RandU32%w;
drops[cur_drop].y=0;
}
for (i=0;i<NUM_DROPS;i++) {
if (drops[i].y>=0) {
if (drops[i].y>=h-1)
drops[i].y=-MAX_I32;
else {
x0=x1=drops[i].x;
y0=y1=drops[i].y;
if (GrPeek(cur_dc,x0,y0+1)==WHITE)
y1++;
else {
c1=GrPeek(cur_dc,x0+1,y0);
c2=GrPeek(cur_dc,x0-1,y0);
if (c1==WHITE && c2!=WHITE)
x1++;
else if (c2==WHITE && c1!=WHITE)
x1--;
else if (c1==WHITE && c2==WHITE) {
c1=GrPeek(cur_dc,x0+1,y0+1);
c2=GrPeek(cur_dc,x0-1,y0+1);
if (c1==WHITE && c2!=WHITE)
x1++;
else if (c2==WHITE && c1!=WHITE)
x1--;
else if (RandI16>=0)
x1++;
else
x1--;
}
if (GrPeek(cur_dc,x1,y1+1)==WHITE)
y1++;
}
if (GrPeek(cur_dc,x0,y0)==BLUE) {
cur_dc->color=WHITE;
GrPlot(cur_dc,x0,y0);
}
cur_dc->color=BLUE;
GrPlot(cur_dc,x1,y1);
drops[i].x=x1;
drops[i].y=y1;
}
}
}
Sleep(10);
}
}
U0 Init()
{
I64 i;
MemSet(drops,0,sizeof(drops));
for (i=0;i<NUM_DROPS;i++)
drops[i].y=-MAX_I32;
}
U0 RainDrops()
{
I64 ch,sc;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" OpenUpper(,'1');"
" OpenLower(,'2');"
"}"
);
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
WinMax;
cur_dc=DCNew(GR_WIDTH,GR_HEIGHT);
sc_1=A2ScanCode('1');
sc_2=A2ScanCode('2');
Init;
Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
WordStat;
try {
do {
ch=GetKey(&sc);
switch (ch) {
case '\n':
Init;
break;
}
} while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
} catch
PutExcept;
SettingsPop;
MenuPop;
DCDel(cur_dc);
}
RainDrops;
+523
View File
@@ -0,0 +1,523 @@
//This uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CPP"$.
AcctRegSetDftEntry("TempleOS/RawHide","F64 best_score=9999;\n");
AcctRegExeBranch("TempleOS/RawHide");
F64 t0,tf;
#define MAP_WIDTH 1500
#define MAP_HEIGHT 1500
#define MAP_BORDER 3
CDC *dc2;
$BG,10$
#define GE_COW 0
$SP,"<1>",BI=1$
#define GE_BULL 1
$SP,"<2>",BI=2$
#define GE_HORSE 2
$SP,"<3>",BI=3$
#define GE_NUM 3
$BG$
class RHCSprite
{
U8 *img;
I64 min_x,max_x,min_y,max_y;
} rh_sprite[GE_NUM];
#define NUM_ANIMALS 128
class Animal
{
I64 num,x,y,dx,dy;
RHCSprite *ge;
U32 buddy;
U8 type;
Bool dead,pad[2];
} *a;
// ************************************
#define COURSE_LEN (MAP_HEIGHT*2)
I32 *rx,*ry,*rw;
I64 river_lo,river_hi;
U0 RiverNew()
{
rx=MAlloc(COURSE_LEN*sizeof(I32));
ry=MAlloc(COURSE_LEN*sizeof(I32));
rw=MAlloc(COURSE_LEN*sizeof(I32));
river_lo=river_hi=COURSE_LEN/2;
}
U0 RiverMake()
{
I64 i,x,y,dx,dy,w,old_x,old_y;
//Plan lower course of river
old_x=-1;old_y=-1;
x=MAP_WIDTH<<32/2; y=MAP_HEIGHT<<32/2;
dx=0; dy=1<<32;
w=20<<32;
i=COURSE_LEN/2;
while (y.i32[1]<MAP_HEIGHT-MAP_BORDER && i<COURSE_LEN) {
if (old_x.i32[1]!=x.i32[1]||old_y.i32[1]!=y.i32[1]) {
rx[i]=x.i32[1]; ry[i]=y.i32[1]; rw[i]=w.i32[1];
river_hi=i++;
old_x=x; old_y=y;
}
dx=ClampI64(dx+RandI32/64,-MAX_I32,MAX_I32);
dy=ClampI64(dy+RandI32/64,0,MAX_I32);
x+=dx; y+=dy;
w=ClampI64(w+RandI32*2,10*MAX_U32,150*MAX_U32);
}
//Plan upper course of river
old_x=-1;old_y=-1;
x=MAP_WIDTH<<32/2; y=MAP_HEIGHT<<32/2;
dx=0; dy=-1<<32;
w=20<<32;
i=COURSE_LEN/2-1;
while (y.i32[1]>=MAP_BORDER && i>=0) {
if (old_x.i32[1]!=x.i32[1]||old_y.i32[1]!=y.i32[1]) {
rx[i]=x.i32[1]; ry[i]=y.i32[1]; rw[i]=w.i32[1];
river_lo=i--;
old_x=x; old_y=y;
}
dx=ClampI64(dx+RandI32/64,-MAX_I32,MAX_I32);
dy=ClampI64(dy+RandI32/64,-MAX_I32,0);
x+=dx; y+=dy;
w=ClampI64(w+RandI32*2,10*MAX_U32,150*MAX_U32);
}
//Plot sand bar
x=0; y=0;
for (i=river_lo;i<=river_hi;i++) {
dc2->color=YELLOW;
dc2->pen_width=rw[i]+5;
GrPlot3(dc2,rx[i]+x.i32[1],ry[i]+y.i32[1],0);
x=ClampI64(x+RandI32,-6*MAX_U32,6*MAX_U32);
y=ClampI64(y+RandI32,-6*MAX_U32,6*MAX_U32);
}
//Plot water
for (i=river_lo;i<=river_hi;i++) {
dc2->color=BLUE;
dc2->pen_width=rw[i];
GrPlot3(dc2,rx[i],ry[i],0);
}
}
U0 RiverDel()
{
Free(rx);
Free(ry);
Free(rw);
}
// ************************************
class RiverDrop
{
RiverDrop *next,*last;
I64 index,dx,dy;
} rd_root;
Bool rd_lock;
U0 RiverDropsDel()
{
while (LBts(&rd_lock,0))
Yield;
QueDel(&rd_root,TRUE);
QueInit(&rd_root);
LBtr(&rd_lock,0);
}
U0 RiverDropsNext(CTask *mem_task)
{
RiverDrop *tempr,*tempr1;
while (LBts(&rd_lock,0))
Yield;
tempr=rd_root.next;
while (tempr!=&rd_root) {
tempr1=tempr->next;
if (++tempr->index>river_hi) {
QueRem(tempr);
Free(tempr);
} else {
do {
if (RandU16&1 &&
GrPeek(dc2,rx[tempr->index]+tempr->dx,ry[tempr->index]+tempr->dy)==BLUE)
break;
tempr->dx=ClampI64(tempr->dx+RandU16%3-1,-rw[tempr->index]/2,rw[tempr->index]/2);
tempr->dy=ClampI64(tempr->dy+RandU16%3-1,-rw[tempr->index]/2,rw[tempr->index]/2);
} while (GrPeek(dc2,rx[tempr->index]+tempr->dx,ry[tempr->index]+tempr->dy)!=BLUE &&
GrPeek(dc2,rx[tempr->index] ,ry[tempr->index]) ==BLUE); //Might be reinitializing
}
tempr=tempr1;
}
tempr=MAlloc(sizeof(RiverDrop),mem_task);
tempr->index=river_lo;
tempr->dx=0;
tempr->dy=0;
QueIns(tempr,rd_root.last);
LBtr(&rd_lock,0);
}
U0 RiverDropsDraw(CDC *dc,I64 cx,I64 cy)
{
RiverDrop *tempr;
dc->color=LTBLUE;
while (LBts(&rd_lock,0))
Yield;
tempr=rd_root.next;
while (tempr!=&rd_root) {
GrPlot(dc,rx[tempr->index]+tempr->dx-cx,ry[tempr->index]+tempr->dy-cy);
tempr=tempr->next;
}
LBtr(&rd_lock,0);
}
// ************************************
U0 DrawIt(CTask *task,CDC *dc)
{
static I64 last_ipx=0;
static Bool left=TRUE;
F64 t;
I64 i,
cx=(MAP_WIDTH -task->pix_width)/2,
cy=(MAP_HEIGHT-task->pix_height)/2;
if (task->scroll_x+cx<0)
task->scroll_x=-cx;
if (task->scroll_x+cx>MAP_WIDTH-task->pix_width)
task->scroll_x=MAP_WIDTH-task->pix_width-cx;
if (task->scroll_y+cy<0)
task->scroll_y=-cy;
if (task->scroll_y+cy>MAP_HEIGHT-task->pix_height)
task->scroll_y=MAP_HEIGHT-task->pix_height-cy;
dc2->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,-cx,-cy,dc2);
RiverDropsDraw(dc,cx,cy);
for (i=0;i<NUM_ANIMALS;i++)
if (!a[i].dead) {
if (a[i].dx<0) {
dc->flags|=DCF_JUST_MIRROR|DCF_SYMMETRY;
GrSetSymmetry(dc,a[i].x.i32[1]-cx,0,a[i].x.i32[1]-cx,1);
}
Sprite3(dc,a[i].x.i32[1]-cx,a[i].y.i32[1]-cy,0,a[i].ge->img);
dc->flags&=~(DCF_JUST_MIRROR|DCF_SYMMETRY);
}
if (ipx-last_ipx>0)
left=FALSE;
else if (ipx-last_ipx<0)
left=TRUE;
if (left) {
dc->flags|=DCF_JUST_MIRROR|DCF_SYMMETRY;
GrSetSymmetry(dc,ipx-task->pix_left-task->scroll_x,0,ipx-task->pix_left-task->scroll_x,1);
}
Sprite3(dc,
ipx-task->pix_left-task->scroll_x,
ipy-task->pix_top -task->scroll_y,0,rh_sprite[GE_HORSE].img);
dc->flags&=~(DCF_JUST_MIRROR|DCF_SYMMETRY);
last_ipx=ipx;
if (tf) {
dc->color=RED;
t=tf-t0;
if (Blink)
GrPrint(dc,(task->pix_width-FONT_WIDTH*14)>>1-task->scroll_x,
(task->pix_height-FONT_HEIGHT)>>1-task->scroll_y,
"Game Completed");
} else {
dc->color=BLACK;
t=tS-t0;
}
GrPrint(dc,-task->scroll_x,-task->scroll_y,"Time:%7.2fs Best:%7.2fs",t,best_score);
}
U0 BuddySelect(I64 i)
{
I64 b,best_b=i,score,best_score=MAX_I64;
for (b=0;b<NUM_ANIMALS;b++) {
if (b!=i && !a[b].dead) {
score=RandU32%(512*512)+
SqrI64(a[b].x.i32[1]-a[i].x.i32[1])+
SqrI64(a[b].y.i32[1]-a[i].y.i32[1]);
if (score<best_score) {
best_score=score;
best_b=b;
}
}
}
a[i].buddy=best_b;
}
U0 AnimateTask(CTask *parent)
{
I64 i,cx,cy,cursor_x,cursor_y,dd,ddx,ddy,cnt,max_speed=MAX_I64,
min_x,max_x,min_y,max_y,updates=0;
F64 f,d,dx,dy,s,stress;
Animal *tempa,*tempa1;
while (TRUE) {
max_speed=ClampU64(max_speed,MAX_U32/3,200*MAX_U32);
cx=(MAP_WIDTH -parent->pix_width)/2,
cy=(MAP_HEIGHT-parent->pix_height)/2;
cursor_x=ipx+cx-parent->pix_left-parent->scroll_x;
cursor_y=ipy+cy-parent->pix_top -parent->scroll_y;
min_x=max_x=min_y=max_y=cnt=0;
stress=0;
for (i=0;i<NUM_ANIMALS;i++) {
tempa=&a[i];
if (!tempa->dead) {
//Move away from horse
ddx=tempa->x.i32[1]-cursor_x;
ddy=tempa->y.i32[1]-cursor_y;
if (dd=SqrI64(ddx)+SqrI64(ddy)) {
d=Sqrt(dd);
dx=ddx/d;
dy=ddy/d;
f=2.0e2*MAX_U32/dd;
tempa->dx+=f*dx;
tempa->dy+=f*dy;
}
//Reselect buddy about every NUM_ANIMALS*10ms=5.12 seconds
tempa1=&a[tempa->buddy];
if (tempa1->dead || i==updates%NUM_ANIMALS) {
BuddySelect(i);
tempa1=&a[tempa->buddy];
}
//Move toward buddy
ddx=tempa->x.i32[1]-tempa1->x.i32[1];
ddy=tempa->y.i32[1]-tempa1->y.i32[1];
if (dd=SqrI64(ddx)+SqrI64(ddy)) {
d=Sqrt(dd);
s=d`1.25-80;
stress+=Abs(s);
dx=ddx/d;
dy=ddy/d;
f=-0.001*s*MAX_U32;
tempa->dx+=f*dx;
tempa->dy+=f*dy;
}
//Make velocity similar to buddy
tempa->dx+=0.1*(tempa1->dx-tempa->dx);
tempa->dy+=0.1*(tempa1->dy-tempa->dy);
//Add random movement, limit speed and dampen speed
tempa->dx=0.995*ClampI64(tempa->dx+RandI32/32,-max_speed,max_speed);
tempa->dy=0.995*ClampI64(tempa->dy+RandI32/32,-max_speed,max_speed);
//Slow in river
if (GrPeek(dc2,tempa->x.i32[1],tempa->y.i32[1])!=LTGREEN) {
tempa->dx/=4;
tempa->dy/=4;
}
tempa->x+=tempa->dx;
tempa->y+=tempa->dy;
//Keep on map
if (!(MAP_BORDER-tempa->ge->min_x<=tempa->x.i32[1]<MAP_WIDTH-MAP_BORDER-tempa->ge->max_x)) {
tempa->x -=tempa->dx;
tempa->dx=-tempa->dx;
}
if (!(MAP_BORDER-tempa->ge->min_y<=tempa->y.i32[1]<MAP_HEIGHT-MAP_BORDER-tempa->ge->max_y)) {
tempa->y -=tempa->dy;
tempa->dy=-tempa->dy;
}
if (cnt) {
min_x=MinI64(min_x,tempa->x);
max_x=MaxI64(max_x,tempa->x);
min_y=MinI64(min_y,tempa->y);
max_y=MaxI64(max_y,tempa->y);
} else {
min_x=max_x=tempa->x;
min_y=max_y=tempa->y;
}
cnt++;
}
}
if (!(updates&15))
RiverDropsNext(parent);
if (!tf && (max_x-min_x)>>32<GR_WIDTH && (max_y-min_y)>>32<GR_HEIGHT) {
tf=tS;
music_mute=TRUE;
Snd(2000);Sleep(200);Snd(0);Sleep(100);
if (tf-t0<best_score) {
best_score=tf-t0;
Snd(2000);Sleep(200);Snd(0);Sleep(100);
}
music_mute=FALSE;
}
updates++;
if (cnt)
stress/=cnt;
else
stress=0;
if (stress>100.0) {
Yield;
max_speed=stress/5.0*MAX_U32; //Converge faster at start-up
} else {
Sleep(10);
max_speed=0; //Will be set to normal max speed
}
}
}
U0 SongTask(I64)
{ //Randomly generated (by God :-)
Fs->task_end_cb=&SndTaskEndCB;
MusicSettingsRst;
while (TRUE) {
Play("3qC2etG3DCBDCECFqFCsADADqB");
Play("C2etG3DCBDCECFqFCsADADqB");
Play("2sG3A2G3AqG2etG3GDeBBqBFeBAqE");
Play("2sG3A2G3AqG2etG3GDeBBqBFeBAqE");
}
}
U0 ReInit()
{
I64 i;
RiverDropsDel;
dc2->color=LTGREEN;
GrRect(dc2,2,2,MAP_WIDTH-4,MAP_HEIGHT-4);
RiverMake;
dc2->pen_width=MAP_BORDER;
dc2->color=RED;
GrLineRect4(dc2,MAP_BORDER/2,MAP_BORDER/2,MAP_WIDTH-(MAP_BORDER+1)/2,MAP_HEIGHT-(MAP_BORDER+1)/2);
for (i=river_lo;i<=river_hi;i++)
RiverDropsNext(Fs);
MemSet(a,0,NUM_ANIMALS*sizeof(Animal));
for (i=0;i<NUM_ANIMALS;i++) {
a[i].num=i;
a[i].x=(64+RandU32%(MAP_WIDTH-128))<<32;
a[i].y=(64+RandU32%(MAP_WIDTH-128))<<32;
if (i&1)
a[i].ge=&rh_sprite[GE_COW];
else
a[i].ge=&rh_sprite[GE_BULL];
BuddySelect(i);
}
t0=tS;
tf=0;
}
U0 Init()
{
I64 i;
RHCSprite *ge;
rh_sprite[0].img=$IB,"<1>",BI=1$;
rh_sprite[1].img=$IB,"<2>",BI=2$;
rh_sprite[2].img=$IB,"<3>",BI=3$;
for (i=0;i<GE_NUM;i++) {
ge=&rh_sprite[i];
SpriteExtents(ge->img,&ge->min_x,&ge->max_x,&ge->min_y,&ge->max_y);
}
RiverNew;
rd_lock=0;
QueInit(&rd_root);
dc2=DCNew(MAP_WIDTH,MAP_HEIGHT);
a=MAlloc(NUM_ANIMALS*sizeof(Animal));
ReInit;
}
U0 CleanUp()
{
DCDel(dc2);
Free(a);
RiverDropsDel;
RiverDel;
}
U0 RawHide()
{
I64 msg_code,p1,p2;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
PopUpOk(
"Coral the cattle into an area\n"
"the size of a screen.\n\n"
"Scroll with {CTRL-Left Grab}.\n"
"Center with {CTRL-Right}.");
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
"}"
);
Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
Fs->win_inhibit=WIG_TASK_DFT-WIF_FOCUS-WIF_BORDER-WIF_GRAB_SCROLL-WIF_MENU;
WinMax;
WordStat;
Preempt(OFF);
Init;
Fs->animate_task=Spawn(&AnimateTask,Fs,"Animate",,Fs);
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
try {
while (TRUE) {
msg_code=GetMsg(&p1,&p2,1<<MSG_KEY_DOWN+1<<MSG_IP_L_DOWN+1<<MSG_IP_R_DOWN);
switch (msg_code) {
case MSG_IP_L_DOWN: //Doesn't do anything, yet.
break;
case MSG_IP_R_DOWN: //Doesn't do anything, yet.
break;
case MSG_KEY_DOWN:
switch (p1) {
case '\n':
ReInit;
break;
case CH_SHIFT_ESC:
case CH_ESC:
goto rh_done;
}
break;
}
}
rh_done:
GetMsg(,,1<<MSG_KEY_UP);
} catch
PutExcept;
MenuPop;
SettingsPop;
CleanUp;
AcctRegWriteBranch("TempleOS/RawHide","F64 best_score=%5.4f;\n",best_score);
}
RawHide;
òöÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿböÿÿÿôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂöÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
Binary file not shown.
Binary file not shown.
+415
View File
@@ -0,0 +1,415 @@
#define MT_HOSE 1
#define MT_DROPLET 2
class MyMass:CMass
{
I64 type;
F64 radius;
};
#define ST_HOSE 1
class MySpring:CSpring
{
I64 type;
};
$BG,11$
$SP,"<1>",BI=1$
$SP,"<2>",BI=2$
$SP,"<3>",BI=3$
$BG$
$SP,"<4>",BI=4,BP="::/Demo/Graphics/Camp.CPP.Z,Mountain"$ //Pointer to sprite in Camp.CPP.Z file
#define HOSE_RADIUS 3
#define LINK_SIZE 6
#define NOZZLE_START_Y (GR_HEIGHT-15*FONT_HEIGHT)
#define NOZZLE_LEN 18
#define FAUCET_X (5*HOSE_RADIUS)
#define FAUCET_Y (GR_HEIGHT-12*FONT_HEIGHT)
#define GROUND_Y (GR_HEIGHT-3*FONT_HEIGHT)
MyMass *faucet,*nozzle;
F64 nozzle_é;
CMathODE *ode=NULL;
F64 start_up_timeout;
U0 DrawIt(CTask *task,CDC *dc)
{
Bool old_suspend,first;
F64 dx,dy,d;
I64 x1b,y1b,x2b,y2b,
x1a,y1a,x2a,y2a;
MyMass *tempm,*tempm1;
MySpring *temps;
CD3I32 poly[4];
Sprite3(dc,0,GROUND_Y,0,$IB,"<4>",BI=4$);
if (start_up_timeout>tS) {
ode->drag_v2=0.01; //Let hose settle during start-up
ode->drag_v3=0.0001;
dc->color=RED;
GrPrint(dc,(GR_WIDTH-FONT_WIDTH*6)>>1,GR_HEIGHT>>1,"Squirt");
return;
} else {
ode->drag_v2=0.0005;
ode->drag_v3=0.0000025;
}
old_suspend=Suspend(task);
tempm=faucet;
dc->color=BLACK;
GrRect(dc,tempm->x+8,tempm->y,8,GROUND_Y-FAUCET_Y);
Sprite3(dc,tempm->x,tempm->y,0,$IB,"<1>",BI=1$);
dc->color=BLACK;
GrCircle(dc,tempm->x,tempm->y,tempm->radius);
dc->color=GREEN;
GrFloodFill(dc,tempm->x,tempm->y);
tempm=nozzle;
tempm1=nozzle->last;
dx=tempm->x-tempm1->x;
dy=tempm->y-tempm1->y;
nozzle_é=Wrap(Arg(dx,dy));
SpriteZ3B(dc,tempm->x,tempm->y,0,$IB,"<2>",BI=2$,nozzle_é);
dc->color=BLACK;
GrCircle(dc,tempm->x,tempm->y,tempm->radius);
dc->color=GREEN;
GrFloodFill(dc,tempm->x,tempm->y);
first=TRUE;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
if (tempm->type==MT_HOSE) {
tempm1=tempm->last;
dx=tempm->x-tempm1->x;
dy=tempm->y-tempm1->y;
d=HOSE_RADIUS/Max(Sqrt(dx*dx+dy*dy),0.001);
dx*=d;
dy*=d;
x2a=tempm->x-dy;
y2a=tempm->y+dx;
x2b=tempm->x+dy;
y2b=tempm->y-dx;
if (first)
first=FALSE;
else {
dc->color=GREEN;
poly[0].x=x1a;
poly[0].y=y1a;
poly[0].z=0;
poly[1].x=x2a;
poly[1].y=y2a;
poly[1].z=0;
poly[2].x=x2b;
poly[2].y=y2b;
poly[2].z=0;
poly[3].x=x1b;
poly[3].y=y1b;
poly[3].z=0;
GrFillPoly3(dc,4,poly);
}
//Fill gaps
GrLine(dc,x2a,y2a,x2b,y2b);
x1a=x2a;
y1a=y2a;
x1b=x2b;
y1b=y2b;
} else if (tempm->type==MT_DROPLET)
Sprite3(dc,tempm->x,tempm->y,0,$IB,"<3>",BI=3$);
tempm=tempm->next;
}
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
if (temps->type==ST_HOSE) {
dx=temps->end1->x-temps->end2->x;
dy=temps->end1->y-temps->end2->y;
d=HOSE_RADIUS/Max(Sqrt(dx*dx+dy*dy),0.001);
dx*=d;
dy*=d;
dc->color=BLACK;
GrLine(dc,temps->end1->x-dy,temps->end1->y+dx,
temps->end2->x-dy,temps->end2->y+dx);
GrLine(dc,temps->end1->x+dy,temps->end1->y-dx,
temps->end2->x+dy,temps->end2->y-dx);
}
temps=temps->next;
}
Suspend(task,old_suspend);
}
U0 MyDerivative(CMathODE *ode,F64 t,COrder2D3 *state,COrder2D3 *DstateDt)
{
//The forces due to springs and drag are
//automatically handled by the
//ode code. We can add new forces
//here.
nounusedwarn t,state,DstateDt;
// F64 d,dd;
// CD3 p;
MyMass *tempm1,*tempm2;
nounusedwarn tempm2;
tempm1=ode->next_mass;
while (tempm1!=&ode->next_mass) {
if (tempm1->type==MT_HOSE) {
if (tempm1->state->y+tempm1->radius>GROUND_Y)
tempm1->DstateDt->DyDt-=Sqr(Sqr(tempm1->state->y+tempm1->radius-GROUND_Y))*tempm1->mass;
else
tempm1->DstateDt->DyDt+=500*tempm1->mass;
if (tempm1==nozzle || tempm1==faucet) {
tempm1->DstateDt->DxDt=0;
tempm1->DstateDt->DyDt=0;
}
} else if (tempm1->type==MT_DROPLET)
tempm1->DstateDt->DyDt=500*tempm1->mass;
tempm1=tempm1->next;
}
}
MyMass *PlaceMass(I64 type,I64 x, I64 y,F64 r,F64 dx,F64 dy,F64 mass,CTask *mem_task)
{
MyMass *tempm=CAlloc(sizeof(MyMass),mem_task);
tempm->type=type;
tempm->mass=mass;
tempm->drag_profile_factor=250.0;
tempm->x=x;
tempm->y=y;
tempm->DxDt=dx;
tempm->DyDt=dy;
tempm->radius=r;
QueIns(tempm,ode->last_mass);
return tempm;
}
MySpring PlaceSpring(MyMass *tempm1,MyMass *tempm2)
{
MySpring *temps=CAlloc(sizeof(MySpring));
temps->end1=tempm1;
temps->end2=tempm2;
temps->const=20000;
QueIns(temps,ode->last_spring);
return temps;
}
U0 HoseNew()
{
I64 i;
MyMass *tempm1=NULL,*tempm;
MySpring *temps;
for (i=FAUCET_X;i<GR_WIDTH;i+=LINK_SIZE) {
tempm=PlaceMass(MT_HOSE,i/2,GROUND_Y-HOSE_RADIUS,HOSE_RADIUS,0,0,1.0,Fs);
if (tempm1) {
temps=PlaceSpring(tempm,tempm1);
temps->rest_len=LINK_SIZE;
temps->type=ST_HOSE;
nozzle=tempm;
} else
faucet=tempm;
tempm1=tempm;
}
faucet->y=FAUCET_Y;
nozzle->y=NOZZLE_START_Y;
nozzle_é=0;
}
U0 AnimateTask(I64)
{
//Preempt is off by default for new task
MyMass *tempm,*tempm1;
F64 dx,dy;
while (TRUE) {
//The WinMgr task suspends our parent when it
//updates the ODE's. We use this to know when
//the ODE's are being updated.
if (!IsSuspended(Fs->parent_task)) {
dx=Cos(nozzle_é),
dy=Sin(nozzle_é),
PlaceMass(MT_DROPLET,
nozzle->x+NOZZLE_LEN*dx,nozzle->y+NOZZLE_LEN*dy,
HOSE_RADIUS,
500*dx,500*dy,
100.0,Fs->parent_task);
if (Rand<0.05) //faucet drip
PlaceMass(MT_DROPLET,
faucet->x,faucet->y,
HOSE_RADIUS,
0,0,
100.0,Fs->parent_task);
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
tempm1=tempm->next;
if (tempm->type==MT_DROPLET &&
tempm->y+tempm->radius>GROUND_Y) {
QueRem(tempm);
Free(tempm);
}
tempm=tempm1;
}
}
WinMgrSync;
}
}
#define NOZZLE_MOVE_STEPS 5
#define NOZZLE_MOVE 15.0
U0 MoveNozzleTaskX(I64 sign)
{
I64 i;
for (i=0;i<NOZZLE_MOVE_STEPS;i++) {
nozzle->x=Clamp(nozzle->x+
sign*NOZZLE_MOVE/NOZZLE_MOVE_STEPS,
HOSE_RADIUS*3,GR_WIDTH-HOSE_RADIUS*3);
WinMgrSync;
}
}
U0 MoveNozzleTaskY(I64 sign)
{
I64 i;
for (i=0;i<NOZZLE_MOVE_STEPS;i++) {
nozzle->y=Clamp(nozzle->y+
sign*NOZZLE_MOVE/NOZZLE_MOVE_STEPS,
HOSE_RADIUS*3,GROUND_Y);
WinMgrSync;
}
}
U0 Init()
{
DocClear;
"$$BG,LTCYAN$$"; NewLine(GROUND_Y/FONT_HEIGHT);
//Allow hose to settle.
start_up_timeout=tS+0.5;
ode=ODENew(0,5e-2,ODEF_HAS_MASSES);
ode->derivative=&MyDerivative;
ode->acceleration_limit=5e3;
HoseNew;
QueIns(ode,Fs->last_ode);
}
U0 CleanUp()
{
WinMgrSync(NOZZLE_MOVE_STEPS); //Let nozzle move tasks die
QueRem(ode);
QueDel(&ode->next_mass,TRUE);
QueDel(&ode->next_spring,TRUE);
ODEDel(ode);
DocClear;
}
U0 SongTask(I64)
{
Fs->task_end_cb=&SndTaskEndCB;
MusicSettingsRst;
while (TRUE) {
Play("3eAM4/4");
Play("2qGeGqG3eAq.BqBeBqA2eG3qA");
Play("eB2hG3q.BqBeCq.DD");
Play("qCeBqCeDhB");
}
}
U0 Squirt()
{
I64 sc;
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
Fs->text_attr=YELLOW<<4+BLUE;
Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
WinMax;
WinBorder;
Preempt(OFF);
DocCursor;
WordStat;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" Left(,,SC_CURSOR_LEFT);"
" Right(,,SC_CURSOR_RIGHT);"
" Up(,,SC_CURSOR_UP);"
" Down(,,SC_CURSOR_DOWN);"
"}"
);
Init;
Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
Fs->draw_it=&DrawIt;
try {
while (TRUE) {
switch (GetKey(&sc)) {
case 0:
switch (sc.u8[0]) {
case SC_CURSOR_LEFT:
Spawn(&MoveNozzleTaskX,-1,"Move Nozzle",,Fs);
break;
case SC_CURSOR_RIGHT:
Spawn(&MoveNozzleTaskX,1,"Move Nozzle",,Fs);
break;
case SC_CURSOR_UP:
Spawn(&MoveNozzleTaskY,-1,"Move Nozzle",,Fs);
break;
case SC_CURSOR_DOWN:
Spawn(&MoveNozzleTaskY,1,"Move Nozzle",,Fs);
break;
}
break;
case '\n':
CleanUp;
Init;
break;
case CH_SHIFT_ESC:
case CH_ESC:
goto sq_done;
}
}
sq_done: //Don't goto out of try
} catch
PutExcept;
SettingsPop;
CleanUp;
MenuPop;
}
Squirt;
R÷ÿÿÿìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2 ÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJýÿÿÿýÿÿÿÿÿÿ ÿÿ ÿ ÿÿ  ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
Binary file not shown.
Binary file not shown.
Binary file not shown.
+33
View File
@@ -0,0 +1,33 @@
//Generate "Stadium.GRA.Z" from "Stadium.TXT.Z"
U0 StadiumGen()
{
U0 (*fp_old_update)(CDC *dc);
CDC *dc,*dc2;
WinMax;
WinBorder;
WordStat;
DocClear;
Type("::/Demo/Games/Stadium/Stadium.TXT");
"$$CM,0,%d$$",TEXT_ROWS-3;
DocCursor(OFF);
fp_old_update=fp_final_screen_update; //hide mouse cursor
fp_final_screen_update=NULL;
WinMgrSync(2,TRUE);
dc2=DCCaptureScreen;
dc=DCExtract(dc2,0,FONT_HEIGHT,GR_WIDTH,GR_HEIGHT);
DCDel(dc2);
GRAWrite("::/Demo/Games/Stadium/Stadium",dc);
DCDel(dc);
DocCursor(ON);
fp_final_screen_update=fp_old_update;
DocClear;
}
StadiumGen;
Binary file not shown.
+130
View File
@@ -0,0 +1,130 @@
I8 board [9];
I64 board_x[9]={150,250,350,150,250,350,150,250,350};
I64 board_y[9]={150,150,150,250,250,250,350,350,350};
U0 DrawX(CDC *dc,I64 x,I64 y)
{
dc->pen_width=5;
GrLine3(dc,x-20,y-20,0,x+20,y+20,0);
GrLine3(dc,x+20,y-20,0,x-20,y+20,0);
}
U0 DrawO(CDC *dc,I64 x,I64 y)
{
dc->pen_width=5;
GrCircle3(dc,x,y,0,25);
}
U0 DrawBoard(I64 player)
{
I64 i;
CDC *dc=DCAlias;
DCFill;
dc->pen_width=5;
GrLine3(dc,200,100,0,200,400,0);
GrLine3(dc,300,100,0,300,400,0);
GrLine3(dc,100,200,0,400,200,0);
GrLine3(dc,100,300,0,400,300,0);
for (i=0;i<9;i++)
switch (board[i]) {
case 1:
DrawX(dc,board_x[i],board_y[i]);
break;
case 2:
DrawO(dc,board_x[i],board_y[i]);
break;
}
/*
ipx,ipy are input pointer (mouse) x,y.
ip_lb is mouse left button
*/
if (player==1)
DrawX(dc,ipx-Fs->pix_left,ipy-Fs->pix_top);
else
DrawO(dc,ipx-Fs->pix_left,ipy-Fs->pix_top);
DCDel(dc);
}
U0 TakeTurn(I64 player)
{
I64 i,x=0,y=0;
while (!(100<=x<400) || !(100<=y<400) || board[i]) {
if (player==1)
Beep(500);
else
Beep(1000);
while (!ip_lb) {
DrawBoard(player);
WinMgrSync;
}
while (ip_lb) {
DrawBoard(player);
WinMgrSync;
}
x=ipx-Fs->pix_left;
y=ipy-Fs->pix_top;
i=(x-100)/100+(y-100)/100*3;
}
board[i]=player;
}
Bool CheckWinner(I64 player)
{
if ( player==board[0]==board[1]==board[2] ||
player==board[3]==board[4]==board[5] ||
player==board[6]==board[7]==board[8] ||
player==board[0]==board[3]==board[6] ||
player==board[1]==board[4]==board[7] ||
player==board[2]==board[5]==board[8] ||
player==board[0]==board[4]==board[8] ||
player==board[2]==board[4]==board[6] )
return TRUE;
else
return FALSE;
}
U0 DoGame()
{
I64 moves=0;
MemSet(board,0,sizeof(board));
while (TRUE) {
TakeTurn(1);
if (CheckWinner(1)) {
Beep(500);
Beep(500);
Beep(500);
break;
}
if (++moves==9) break;
TakeTurn(2);
if (CheckWinner(2)) {
Beep(1000);
Beep(1000);
Beep(1000);
break;
}
if (++moves==9) break;
}
}
U0 TicTacToe()
{
WinMax; //Maximize window
DocClear; //Clear window text.
"$$GREEN$$CTRL-ALT-C$$FG$$ to exit.\n";
try
while (TRUE)
DoGame;
catch
PutExcept;
DCFill;
}
TicTacToe;
+611
View File
@@ -0,0 +1,611 @@
$SP,"<1>",BI=1$
$SP,"<2>",BI=2$
$SP,"<3>",BI=3$
$SP,"<4>",BI=4$
$SP,"<5>",BI=5$
$SP,"<6>",BI=6$
AcctRegSetDftEntry("TempleOS/Varoom","F64 best_score=9999;\n");
AcctRegExeBranch("TempleOS/Varoom");
F64 distance,t0,tf;
Bool game_over;
#define NUM_BUSHES 512
class Bush
{
CD3I32 p;
Bool sym,pad[3];
U8 *img;
} b[NUM_BUSHES];
#define NUM_CARS 8
class Car
{
CD3I32 p;
F64 é,speed;
CSprite *img;
} c[NUM_CARS];
#define TRACK_INNER 16000
#define TRACK_OUTER 18000
#define SHOULDER 200
#define SLICES 500
#define D_é (2*ã/SLICES)
#define TRACK_POLYS (3*SLICES)
#define DIPS 5
#define DIP_DEPTH 100
class TrackPoly
{
CColorROPU16 c,pad[3];
CD3I32 p[4];
} track[TRACK_POLYS];
I64 DipY(I64 x,I64 z)
{
F64 m,a;
R2P(&m,&a,x,z);
return DIP_DEPTH*m*Cos(DIPS*a)/((TRACK_INNER+TRACK_OUTER)/2);
}
#define CAR_LENGTH 400
F64 Dipé(I64 x,I64 z,F64 é)
{
F64 y_front,y_back;
y_front=DipY(x-CAR_LENGTH/2*Cos(é),z-CAR_LENGTH/2*Sin(é));
y_back =DipY(x+CAR_LENGTH/2*Cos(é),z+CAR_LENGTH/2*Sin(é));
return ASin((y_front-y_back)/CAR_LENGTH);
}
U0 InitTrackPoly(TrackPoly *tempt,CColorROPU16 c,
I64 inner,I64 outer,F64 é1,F64 é2)
{
tempt->c=c;
tempt->p[0].x=inner*Cos(é1);
tempt->p[0].z=inner*Sin(é1);
tempt->p[0].y=DipY(tempt->p[0].x,tempt->p[0].z);
tempt->p[1].x=outer*Cos(é1);
tempt->p[1].z=outer*Sin(é1);
tempt->p[1].y=DipY(tempt->p[1].x,tempt->p[1].z);
tempt->p[2].x=outer*Cos(é2);
tempt->p[2].z=outer*Sin(é2);
tempt->p[2].y=DipY(tempt->p[2].x,tempt->p[2].z);
tempt->p[3].x=inner*Cos(é2);
tempt->p[3].z=inner*Sin(é2);
tempt->p[3].y=DipY(tempt->p[3].x,tempt->p[3].z);
}
U0 InitTrack()
{
TrackPoly *tempt=track;
I64 i;
for (i=0;i<SLICES;i++) {
InitTrackPoly(tempt++,DKGRAY,TRACK_INNER,TRACK_OUTER,
i*2*ã/SLICES,(i+1)*2*ã/SLICES);
if (i&1) {
InitTrackPoly(tempt++,RED,TRACK_INNER-SHOULDER,TRACK_INNER,
i*2*ã/SLICES,(i+1)*2*ã/SLICES);
InitTrackPoly(tempt++,WHITE,TRACK_OUTER,TRACK_OUTER+SHOULDER,
i*2*ã/SLICES,(i+1)*2*ã/SLICES);
} else {
InitTrackPoly(tempt++,WHITE,TRACK_INNER-SHOULDER,TRACK_INNER,
i*2*ã/SLICES,(i+1)*2*ã/SLICES);
InitTrackPoly(tempt++,RED,TRACK_OUTER,TRACK_OUTER+SHOULDER,
i*2*ã/SLICES,(i+1)*2*ã/SLICES);
}
}
}
#define HORIZON_DIP 200
I64 mp_not_done_flags;
U0 MPUpdateWin(CDC *dc2)
{
CTask *task=dc2->win_task;
I64 i,j,x,y,z,lo,hi,
w=task->pix_width,
h=task->pix_height,r[16],
cx=w>>1;
F64 s,dip_é=Dipé(c[0].p.x,c[0].p.z,c[0].é);
Car *tempc;
Bool draw;
CD3I32 poly[4];
TrackPoly *tempt;
CDC *dc=DCAlias(gr_dc2,task);
GrIdentEqu(r);
GrRotYEqu(r,ã-c[0].é);
GrRotXEqu(r,75*ã/180-dip_é);
dc->depth_buf=dc2->depth_buf;
//Track
lo=Gs->num*TRACK_POLYS/mp_cnt;
hi=(Gs->num+1)*TRACK_POLYS/mp_cnt;
for (i=lo,tempt=&track[lo];i<hi;i++,tempt++) {
dc->color=tempt->c;
draw=TRUE;
for (j=0;j<4;j++) {
x=tempt->p[j].x-c[0].p.x; y=tempt->p[j].y-c[0].p.y; z=tempt->p[j].z-c[0].p.z;
GrRot(r,&x,&y,&z);
s=100.0/(AbsI64(z)+50);
poly[j].y=s*y+h;
if (z<-200 || !(-h<poly[j].y<2*h)) {
draw=FALSE;
break;
}
poly[j].x=s*x+cx;
poly[j].z=z+GR_Z_ALL;
}
if (draw)
GrFillPoly3(dc,4,poly);
}
dc->flags|=DCF_TRANSFORMATION;
for (i=Gs->num;i<NUM_BUSHES;i+=mp_cnt) {
x=b[i].p.x-c[0].p.x; y=b[i].p.y-c[0].p.y; z=b[i].p.z-c[0].p.z;
GrRot(r,&x,&y,&z);
if (z>0) {
s=100.0/(AbsI64(z)+50);
GrIdentEqu(dc->r);
GrScaleEqu(dc->r,s*2);
GrSetRotMat(dc,dc->r);
if (b[i].sym) {
dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
GrSetSymmetry(dc,s*x+cx,s*y+h,s*x+cx,s*y+h+10);
}
Sprite3B(dc,s*x+cx,s*y+h,z+GR_Z_ALL,b[i].img);
dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
}
}
for (i=Gs->num+1;i<NUM_CARS;i+=mp_cnt) {
tempc=&c[i];
x=tempc->p.x-c[0].p.x; y=tempc->p.y-c[0].p.y; z=tempc->p.z-c[0].p.z;
GrRot(r,&x,&y,&z);
if (z>0) {
s=100.0/(AbsI64(z)+50);
GrIdentEqu(dc->r);
GrScaleEqu(dc->r,s*2);
GrRotXEqu(dc->r,Dipé(tempc->p.x,tempc->p.z,-tempc->é));
GrRotYEqu(dc->r,tempc->é-c[0].é);
GrSetRotMat(dc,dc->r);
Sprite3B(dc,s*x+cx,s*y+h,z+GR_Z_ALL,tempc->img);
}
}
dc->depth_buf=NULL;
DCDel(dc);
LBtr(&mp_not_done_flags,Gs->num);
}
U0 VRTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
{
I64 zz;
GrRot(dc->r,x,y,z);
zz=400+*z;
if (zz<1) zz=1;
*x=400* *x/zz;
*y=400* *y/zz;
*x+=dc->x;
*y+=dc->y;
*z+=dc->z;
}
U0 DrawIt(CTask *task,CDC *dc)
{
I64 i,x,y,z,
w=task->pix_width,
h=task->pix_height,r[16],
cx=w>>1;
F64 s,è,dip_é=Dipé(c[0].p.x,c[0].p.z,c[0].é);
dc->color=LTCYAN;
GrRect(dc,0,0,w,HORIZON_DIP*Sin(dip_é)+FONT_HEIGHT*4.5);
GrIdentEqu(r);
GrRotYEqu(r,ã-c[0].é);
GrRotXEqu(r,75*ã/180-dip_é);
DCAllocDepthBuf(dc);
//Sun
x=c[0].p.x; y=0; z=1000000-c[0].p.z;
GrRot(r,&x,&y,&z);
s=100.0/(AbsI64(z)+50);
if (y<0) {
dc->color=BROWN;
GrCircle(dc,s*x+cx,15+HORIZON_DIP*Sin(dip_é),15);
dc->color=YELLOW;
GrFloodFill(dc,s*x+cx,15+HORIZON_DIP*Sin(dip_é));
}
mp_not_done_flags=1<<mp_cnt-1;
for (i=0;i<mp_cnt;i++)
JobQue(&MPUpdateWin,dc,i);
while (mp_not_done_flags)
Yield;
if (Bt(key_down_bitmap,SC_CURSOR_LEFT))
è=-0.5;
else if (Bt(key_down_bitmap,SC_CURSOR_RIGHT))
è=0.5;
else
è=0;
GrIdentEqu(r);
GrRotYEqu(r,è);
GrRotXEqu(r,0.4-8*dip_é); //Made this up
dc->transform=&VRTransform;
dc->x=task->pix_width>>1;
dc->y=task->pix_height-150;
dc->z=GR_Z_ALL;
SpriteMat3B(dc,0,0,-100,c[0].img,r);
//Map
dc->color=LTGRAY;
GrRect(dc,w-64,h-64,64,64);
dc->color=LTGREEN;
for (i=0;i<NUM_BUSHES;i++)
GrPlot(dc,w-64+64*(0x5000-b[i].p.x)/0xA000,h-64*(-b[i].p.z+0x5000)/0xA000);
dc->pen_width=2;
for (i=0;i<NUM_CARS;i++) {
if (i)
dc->color=LTPURPLE;
else
dc->color=LTCYAN;
GrPlot3(dc,w-64+64*(0x5000-c[i].p.x)/0xA000,h-64*(-c[i].p.z+0x5000)/0xA000,0);
}
if (game_over) {
dc->color=LTRED;
if (tf) {
s=tf-t0;
if (Blink)
GrPrint(dc,(w-FONT_WIDTH*14)/2,(h-FONT_HEIGHT)/2,"Game Completed");
} else {
s=99.9;
if (Blink)
GrPrint(dc,(w-FONT_WIDTH*9)/2,(h-FONT_HEIGHT)/2,"Game Over");
}
} else
s=tS-t0;
dc->color=BLACK;
GrPrint(dc,0,0,"é:%0.1f %0.1f%% Time:%0.2f Best:%0.2f",
180+180/ã*Arg(c[0].p.x,c[0].p.z),100.0*distance/(2*ã*TRACK_INNER),s,best_score);
}
U0 AnimateTask(I64)
{
Car *tempc;
I64 i;
F64 m,a;
while (TRUE) {
if (!game_over)
Snd(c[0].speed*3+10);
else
Snd(0);
for (i=0;i<NUM_CARS;i++) {
tempc=&c[i];
tempc->p.x-=tempc->speed*Cos(tempc->é-ã/2);
tempc->p.z+=tempc->speed*Sin(tempc->é-ã/2);
if (i) {
tempc->é=Arg(-tempc->p.x,tempc->p.z);
tempc->p.x=-(TRACK_INNER+TRACK_OUTER)/2*Cos(tempc->é);
tempc->p.z= (TRACK_INNER+TRACK_OUTER)/2*Sin(tempc->é);
}
tempc->p.y=DipY(tempc->p.x,tempc->p.z);
}
R2P(&m,&a,c[0].p.x,c[0].p.z);
if (!game_over && TRACK_INNER<=m<=TRACK_OUTER) {
for (i=1;i<NUM_CARS;i++)
if (D3I32SqrDist(&c[i].p,&c[0].p)<CAR_LENGTH*CAR_LENGTH>>1) {
game_over=TRUE;
Noise(500,50,100);
Sleep(500);
break;
}
if (!game_over) {
distance+=c[0].speed;
if (distance>2*ã*TRACK_INNER && Wrap(a+ã,-ã)>0.0) {
tf=tS;
game_over=TRUE;
Beep;
if (tf-t0<best_score) {
best_score=tf-t0;
Beep;
}
}
}
}
Sleep(10);
}
}
CSprite *imgs[8]={$IB,"<1>",BI=1$,$IB,"<1>",BI=1$,$IB,"<2>",BI=2$,$IB,"<2>",BI=2$,$IB,"<3>",BI=3$,$IB,"<4>",BI=4$,$IB,"<4>",BI=4$,$IB,"<4>",BI=4$};
U0 Init()
{
Bush *tempb;
Car *tempc;
I64 i;
for (i=0;i<NUM_BUSHES;i++) {
tempb=&b[i];
do {
tempb->p.x=RandU32&0x7FFF-0x4000;
tempb->p.z=RandU32&0x7FFF-0x4000;
} while (TRACK_INNER-SHOULDER<=
Sqrt(SqrI64(tempb->p.x)+SqrI64(tempb->p.z))<=TRACK_OUTER+SHOULDER);
tempb->p.y=DipY(tempb->p.x,tempb->p.z);
tempb->sym=RandU16&1;
tempb->img=imgs[i&7];
}
InitTrack;
for (i=0;i<NUM_CARS;i++) {
tempc=&c[i];
if (i==0) {
tempc->img=$IB,"<5>",BI=5$;
tempc->speed=0;
} else {
tempc->img=$IB,"<6>",BI=6$;
tempc->speed=50.0;
}
tempc->é=i*2*ã/NUM_CARS;
tempc->p.x=-(TRACK_INNER+TRACK_OUTER)/2*Cos(tempc->é);
tempc->p.z= (TRACK_INNER+TRACK_OUTER)/2*Sin(tempc->é);
tempc->p.y=DipY(tempc->p.x,tempc->p.z);
}
distance=0;
tf=0;
t0=tS;
game_over=FALSE;
}
U0 Varoom()
{
I64 ch,sc;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" Accelerator(,,SC_CURSOR_UP);"
" Break(,,SC_CURSOR_DOWN);"
" Left(,,SC_CURSOR_LEFT);"
" Right(,,SC_CURSOR_RIGHT);"
"}"
);
SettingsPush(Fs,TSF_SAME_SONG); //See $LK,"SettingsPush",A="MN:SettingsPush"$
try {
Fs->text_attr=YELLOW<<4+BLUE;
Fs->win_inhibit=WIG_TASK_DFT-WIF_FOCUS-WIF_GRAB_SCROLL-WIF_MENU;
WordStat;
WinMax;
WinBorder;
Preempt(OFF);
Init;
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
while (TRUE) {
while (ScanKey(&ch,&sc))
switch (ch) {
case 0:
switch (sc.u8[0]) {
case SC_CURSOR_LEFT:
c[0].é-=ã/100;
break;
case SC_CURSOR_RIGHT:
c[0].é+=ã/100;
break;
case SC_CURSOR_UP:
c[0].speed+=3;
break;
case SC_CURSOR_DOWN:
c[0].speed-=3;
break;
}
break;
case '\n':
Init;
break;
case CH_SHIFT_ESC:
case CH_ESC:
goto vr_done;
}
WinMgrSync;
}
vr_done: //Don't goto out of try
} catch
Fs->catch_except=TRUE;
SettingsPop(Fs,TSF_SAME_SONG);
MenuPop;
AcctRegWriteBranch("TempleOS/Varoom","F64 best_score=%5.4f;\n",best_score);
}
Varoom;
ö
þÿÿÿèÿÿÿ
ôÿÿÿêÿÿÿ
þÿÿÿîÿÿÿúÿÿÿèÿÿÿ
øÿÿÿúÿÿÿôÿÿÿ
ôÿÿÿìÿÿÿ
âÿÿÿúÿÿÿèÿÿÿ
àÿÿÿ
ìÿÿÿ
îÿÿÿàÿÿÿ
üÿÿÿîÿÿÿ
øÿÿÿâÿÿÿ
øÿÿÿ
öÿÿÿúÿÿÿþÿÿÿ
úÿÿÿüÿÿÿÜÿÿÿ
úÿÿÿðÿÿÿúÿÿÿäÿÿÿã
æÿÿÿöÿÿÿäÿÿÿ
ìÿÿÿìÿÿÿæÿÿÿüÿÿÿ
äÿÿÿÖÿÿÿ
Öÿÿÿæÿÿÿ
æÿÿÿ"àÿÿÿ
êÿÿÿ$äÿÿÿ
ìÿÿÿ$æÿÿÿ
äÿÿÿúÿÿÿäÿÿÿúÿÿÿ
æÿÿÿüÿÿÿæÿÿÿüÿÿÿ
îÿÿÿúÿÿÿ êÿÿÿ
"Üÿÿÿ&æÿÿÿ
äÿÿÿ àÿÿÿ
þÿÿÿ
üÿÿÿ
üÿÿÿðÿÿÿ
êÿÿÿ øÿÿÿ
øÿÿÿèÿÿÿ
èÿÿÿþÿÿÿ
þÿÿÿîÿÿÿ
ìÿÿÿþÿÿÿ
þÿÿÿîÿÿÿ
öÿÿÿ ìÿÿÿ
êÿÿÿðÿÿÿ
ðÿÿÿäÿÿÿ
âÿÿÿðÿÿÿ
ðÿÿÿêÿÿÿ
êÿÿÿúÿÿÿ
 öÿÿÿ”
úÿÿÿÄÿÿÿ
úÿÿÿÄÿÿÿøÿÿÿúÿÿÿ
üÿÿÿÂÿÿÿüÿÿÿ
úÿÿÿÄÿÿÿæÿÿÿ¤ÿÿÿ
üÿÿÿÂÿÿÿäÿÿÿ¤ÿÿÿ
øÿÿÿ¼ÿÿÿúÿÿÿ†ÿÿÿ
Äÿÿÿüÿÿÿ„ÿÿÿ
þÿÿÿºÿÿÿ
Œÿÿÿ
Œÿÿÿüÿÿÿ¸ÿÿÿ
¦ÿÿÿšÿÿÿ
šÿÿÿzÿÿÿ
zÿÿÿ„ÿÿÿ
†ÿÿÿžÿÿÿ
žÿÿÿvÿÿÿ
vÿÿÿþÿÿÿ`ÿÿÿ
þÿÿÿ`ÿÿÿìÿÿÿ„ÿÿÿ
ìÿÿÿ„ÿÿÿöÿÿÿ¬ÿÿÿ
öÿÿÿ¬ÿÿÿâÿÿÿžÿÿÿ
âÿÿÿžÿÿÿØÿÿÿ¨ÿÿÿ
Øÿÿÿ¨ÿÿÿîÿÿÿºÿÿÿ
îÿÿÿºÿÿÿòÿÿÿºÿÿÿ
ôÿÿÿ¸ÿÿÿúÿÿÿ¸ÿÿÿ
–ÿÿÿˆÿÿÿ
„ÿÿÿŠÿÿÿ
þÿÿÿŽÿÿÿþÿÿÿjÿÿÿ
þÿÿÿjÿÿÿôÿÿÿ‚ÿÿÿ
ôÿÿÿ‚ÿÿÿøÿÿÿœÿÿÿ
ôÿÿÿ´ÿÿÿîÿÿÿ¦ÿÿÿ
èÿÿÿ²ÿÿÿÞÿÿÿ¦ÿÿÿ
œÿÿÿ–ÿÿÿ
øÿÿÿ€ÿÿÿhÿÿÿ
ˆÿÿÿ€ÿÿÿ
þÿÿÿ~ÿÿÿnÿÿÿ
~ÿÿÿ’ÿÿÿ
œÿÿÿ¨ÿÿÿ
öÿÿÿ²ÿÿÿðÿÿÿ‚ÿÿÿ
ðÿÿÿ‚ÿÿÿúÿÿÿjÿÿÿ
êÿÿÿ´ÿÿÿÞÿÿÿ ÿÿÿJ␍`ŒFçÿÿÿ}-çÿÿÿ}-çÿÿÿKFçÿÿÿK7ýÿÿÿ‡7ýÿÿÿ–ýÿÿÿ–(ýÿÿÿ‡(ýÿÿÿA7ýÿÿÿA7ýÿÿÿýÿÿÿF}-}-KFK7‡7––(‡(A7A7ºÿÿÿçÿÿÿ}Óÿÿÿçÿÿÿ}ÓÿÿÿçÿÿÿKºÿÿÿçÿÿÿKÉÿÿÿýÿÿÿ‡Éÿÿÿýÿÿÿ–ýÿÿÿ–Øÿÿÿýÿÿÿ‡ØÿÿÿýÿÿÿAÉÿÿÿýÿÿÿAÉÿÿÿýÿÿÿýÿÿÿºÿÿÿ}Óÿÿÿ}ÓÿÿÿKºÿÿÿKÉÿÿÿ‡Éÿÿÿ––Øÿÿÿ‡ØÿÿÿAÉÿÿÿAÉÿÿÿFçÿÿÿƒÿÿÿ-çÿÿÿƒÿÿÿ-çÿÿÿµÿÿÿFçÿÿÿµÿÿÿ7áÿÿÿyÿÿÿ7áÿÿÿjÿÿÿáÿÿÿjÿÿÿ(áÿÿÿyÿÿÿ(áÿÿÿ¿ÿÿÿ7áÿÿÿ¿ÿÿÿ7ýÿÿÿýÿÿÿFƒÿÿÿ-ƒÿÿÿ-µÿÿÿFµÿÿÿ7yÿÿÿ7jÿÿÿjÿÿÿ(yÿÿÿ(¿ÿÿÿ7¿ÿÿÿ7ºÿÿÿçÿÿÿƒÿÿÿÓÿÿÿçÿÿÿƒÿÿÿÓÿÿÿçÿÿÿµÿÿÿºÿÿÿçÿÿÿµÿÿÿÉÿÿÿáÿÿÿyÿÿÿÉÿÿÿáÿÿÿjÿÿÿáÿÿÿjÿÿÿØÿÿÿáÿÿÿyÿÿÿØÿÿÿáÿÿÿ¿ÿÿÿÉÿÿÿáÿÿÿ¿ÿÿÿÉÿÿÿýÿÿÿýÿÿÿºÿÿÿƒÿÿÿÓÿÿÿƒÿÿÿÓÿÿÿµÿÿÿºÿÿÿµÿÿÿÉÿÿÿyÿÿÿÉÿÿÿjÿÿÿjÿÿÿØÿÿÿyÿÿÿØÿÿÿ¿ÿÿÿÉÿÿÿ¿ÿÿÿÉÿÿÿ ␍ ␍   ␍␍
    
$%&&'$%$$$'$%%&&'&#!"!# #     /-.-/,/*,,*++)(+*)+(+ + +(!.-.!" + + ,*)*<=>>?<1033211=<<01<?330<1=2=>2>233?>;9:9;8867754765GEFEGDGBDDBCCA@CBA4C@C474C7C4@9FEF9:8C7C8D5BAB56TUVVWTIHKKJIIUTTHITWKKHTIUJUVJVJKKWVSRQQPSPONOLMOMN_^]]\__\Z\[Z[XY[YZLX[[OLLO[[XLQ]^^RQPO[[\PMYZZNM P88P654@@A5LMYYXLJ␍`ŒFçÿÿÿ}-çÿÿÿ}-çÿÿÿKFçÿÿÿK7ýÿÿÿ‡7ýÿÿÿ–ýÿÿÿ–(ýÿÿÿ‡(ýÿÿÿA7ýÿÿÿA7ýÿÿÿýÿÿÿF}-}-KFK7‡7––(‡(A7A7ºÿÿÿçÿÿÿ}Óÿÿÿçÿÿÿ}ÓÿÿÿçÿÿÿKºÿÿÿçÿÿÿKÉÿÿÿýÿÿÿ‡Éÿÿÿýÿÿÿ–ýÿÿÿ–Øÿÿÿýÿÿÿ‡ØÿÿÿýÿÿÿAÉÿÿÿýÿÿÿAÉÿÿÿýÿÿÿýÿÿÿºÿÿÿ}Óÿÿÿ}ÓÿÿÿKºÿÿÿKÉÿÿÿ‡Éÿÿÿ––Øÿÿÿ‡ØÿÿÿAÉÿÿÿAÉÿÿÿFçÿÿÿƒÿÿÿ-çÿÿÿƒÿÿÿ-çÿÿÿµÿÿÿFçÿÿÿµÿÿÿ7áÿÿÿyÿÿÿ7áÿÿÿjÿÿÿáÿÿÿjÿÿÿ(áÿÿÿyÿÿÿ(áÿÿÿ¿ÿÿÿ7áÿÿÿ¿ÿÿÿ7ýÿÿÿýÿÿÿFƒÿÿÿ-ƒÿÿÿ-µÿÿÿFµÿÿÿ7yÿÿÿ7jÿÿÿjÿÿÿ(yÿÿÿ(¿ÿÿÿ7¿ÿÿÿ7ºÿÿÿçÿÿÿƒÿÿÿÓÿÿÿçÿÿÿƒÿÿÿÓÿÿÿçÿÿÿµÿÿÿºÿÿÿçÿÿÿµÿÿÿÉÿÿÿáÿÿÿyÿÿÿÉÿÿÿáÿÿÿjÿÿÿáÿÿÿjÿÿÿØÿÿÿáÿÿÿyÿÿÿØÿÿÿáÿÿÿ¿ÿÿÿÉÿÿÿáÿÿÿ¿ÿÿÿÉÿÿÿýÿÿÿýÿÿÿºÿÿÿƒÿÿÿÓÿÿÿƒÿÿÿÓÿÿÿµÿÿÿºÿÿÿµÿÿÿÉÿÿÿyÿÿÿÉÿÿÿjÿÿÿjÿÿÿØÿÿÿyÿÿÿØÿÿÿ¿ÿÿÿÉÿÿÿ¿ÿÿÿÉÿÿÿ ␍ ␍   ␍␍
  
$%&&'$%$$$'$%%&&'&#!"!# #   /-.-/,/*,,*++)(+*)+(+ + +(!.-.!" + + ,*)*<=>>?<1033211=<<01<?330<1=2=>2>233?>;9:9;8867754765GEFEGDGBDDBCCA@CBA4C@C474C7C4@9FEF9:8C7C8D5BAB56TUVVWTIHKKJIIUTTHITWKKHTIUJUVJVJKKWVSRQQPSPONOLMOMN_^]]\__\Z\[Z[XY[YZLX[[OLLO[[XLQ]^^RQPO[[\PMYZZNM P88P654@@A5LMYYXL
+643
View File
@@ -0,0 +1,643 @@
AcctRegSetDftEntry("TempleOS/Wenceslas","F64 best_score=9999;\n");
AcctRegExeBranch("TempleOS/Wenceslas");
#define BORDER 5
#define KING_STEP 4
$SP,"<1>",BI=1$
$SP,"<2>",BI=2$
$SP,"<3>",BI=3$
$SP,"<4>",BI=4$
$SP,"<5>",BI=5$
$SP,"<6>",BI=6$
$SP,"<7>",BI=7$
#define NUM_FLAKES 0x8000
class Flake
{
U16 x,y;
} flakes[NUM_FLAKES];
#define NUM_TREES 8
class Tree
{
U16 x,y;
I64 fire_frame_index;
} trees[NUM_TREES];
I64 snow_x,snow_y;
I64 king_x,king_y,not_stopped_cnt;
F64 king_é,t0,tf,door_open_t0;
#define NUM_PEASANTS 16
class Peasant
{
Peasant *next,*last;
F64 x,y,é,door_opened_t0;
Bool stopped;
} peasant_root;
class Step
{
Step *next,*last;
U16 x,y;
F64 t0;
} step_root,king_step_root;
U0 DrawIt(CTask *task,CDC *dc)
{
I64 r[16],i,w=task->pix_width,h=task->pix_height;
U8 *img;
Step *temps;
Peasant *tempp;
F64 tt;
Bool old_preempt=Preempt(OFF);
dc->pen_width=1;
for (i=0;i<NUM_TREES;i++) {
if (trees[i].y<=h/2) { //Draw trees behind house
if (trees[i].fire_frame_index) {
if (trees[i].fire_frame_index++&1)
img=$IB,"<4>",BI=4$;
else
img=$IB,"<5>",BI=5$;
} else
img=$IB,"<3>",BI=3$;
Sprite3(dc,trees[i].x,trees[i].y,0,img);
}
}
Sprite3(dc,w/2,h/2,0,$IB,"<6>",BI=6$);
if (tS<door_open_t0+1.0)
Sprite3(dc,w/2,h/2,0,$IB,"<7>",BI=7$);
for (i=0;i<NUM_TREES;i++) {
if (trees[i].y>h/2) { //Draw trees in front of house
if (trees[i].fire_frame_index) {
if (trees[i].fire_frame_index++&1)
img=$IB,"<4>",BI=4$;
else
img=$IB,"<5>",BI=5$;
} else
img=$IB,"<3>",BI=3$;
Sprite3(dc,trees[i].x,trees[i].y,0,img);
}
}
temps=step_root.next;
while (temps!=&step_root) {
if (tS-temps->t0<2.0)
dc->color=DKGRAY;
else
dc->color=LTGRAY;
dc->pen_width=2;
GrPlot3(dc,temps->x,temps->y,0);
temps=temps->next;
}
dc->pen_width=1;
tempp=peasant_root.next;
while (tempp!=&peasant_root) {
GrIdentEqu(r);
GrRotYEqu(r,tempp->é+ã/2);
GrRotXEqu(r,ã/6);
if (tempp->stopped)
dc->color=LTCYAN;
else
dc->color=CYAN;
SpriteMat3B(dc,tempp->x,tempp->y,0,$IB,"<2>",BI=2$,r);
tempp=tempp->next;
}
dc->pen_width=1;
GrIdentEqu(r);
GrRotYEqu(r,king_é+ã/2);
GrRotXEqu(r,ã/6);
SpriteMat3B(dc,king_x,king_y,0,$IB,"<1>",BI=1$,r);
dc->pen_width=1;
dc->color=WHITE;
for (i=0;i<NUM_FLAKES;i++)
GrPlot(dc,(flakes[i].x+snow_x)%task->pix_width,
(flakes[i].y+snow_y)%task->pix_height);
if (tf) {
dc->color=LTRED;
if (Blink)
GrPrint(dc,w/2-(FONT_WIDTH*14)/2,h/2+FONT_HEIGHT,"Game Completed");
tt=tf;
} else {
tt=tS;
}
dc->color=LTBLUE;
GrPrint(dc,0,0,"Freezing Peasants:%d Time:%3.2f Best:%3.2f",
not_stopped_cnt,tt-t0,best_score);
Preempt(old_preempt);
}
U0 StepNew(CTask *task,I64 x,I64 y,F64 é,Bool king)
{
Step *temps;
if (king) {
temps=MAlloc(sizeof(Step),task);
temps->x=x;
temps->y=y;
temps->t0=tS;
QueIns(temps,king_step_root.last);
}
temps=MAlloc(sizeof(Step),task);
temps->x=x-3.5*Sin(é)+1.0*Cos(é);
temps->y=y+3.5*Cos(é)+1.0*Sin(é);
temps->t0=tS;
QueIns(temps,step_root.last);
temps=MAlloc(sizeof(Step),task);
temps->x=x+3.5*Sin(é)-1.0*Cos(é);
temps->y=y-3.5*Cos(é)-1.0*Sin(é);
temps->t0=tS;
QueIns(temps,step_root.last);
}
U0 Init()
{
I64 i,min_x,max_x,min_y,max_y,
w=Fs->pix_width,h=Fs->pix_height;
Peasant *tempp;
snow_x=0;
snow_y=0;
for (i=0;i<NUM_FLAKES;i++) {
flakes[i].x=RandU16;
flakes[i].y=RandU16;
}
SpriteExtents($IB,"<3>",BI=3$,&min_x,&max_x,&min_y,&max_y);
for (i=0;i<NUM_TREES;i++) {
trees[i].x=RandU16%(w-2*BORDER-(max_x-min_x+1))+BORDER-min_x;
trees[i].y=RandU16%(h-2*BORDER-(max_y-min_y+1))+BORDER-min_y;
trees[i].fire_frame_index=0;
}
QueInit(&step_root);
QueInit(&king_step_root);
SpriteExtents($IB,"<1>",BI=1$,&min_x,&max_x,&min_y,&max_y);
QueInit(&peasant_root);
for (i=0;i<NUM_PEASANTS;i++) {
tempp=MAlloc(sizeof(Peasant));
tempp->x=RandU16%(w-2*BORDER-(max_x-min_x+1))+BORDER-min_x;
tempp->y=RandU16%(h-2*BORDER-(max_y-min_y+1))+BORDER-min_y;
tempp->é=ã*2*Rand;
tempp->door_opened_t0=0;
tempp->stopped=FALSE;
QueIns(tempp,peasant_root.last);
}
king_x=w/2;
king_y=h/2;
king_é=-ã/2;
door_open_t0=0;
t0=tS;
tf=0;
}
U0 CleanUp()
{
QueDel(&peasant_root,TRUE);
QueDel(&step_root,TRUE);
QueDel(&king_step_root,TRUE);
}
U0 Follow(CTask *,Peasant *tempp)
{
Step *temps=king_step_root.next;
F64 d,best_d=MAX_F64;
while (temps!=&king_step_root) {
if ((d=Sqr(temps->x-tempp->x)+Sqr(temps->y-tempp->y)) &&
d<15*15) {
d+=1000*Sqr(tS-temps->t0);
if (d<best_d) {
best_d=d;
tempp->é=Arg(temps->x-tempp->x,temps->y-tempp->y);
}
}
temps=temps->next;
}
}
U0 AnimateTask(I64)
{//preempt off by default after Spawned
Step *temps,*temps1;
Peasant *tempp;
I64 i,animate_cnt=0,w,h;
while (TRUE) {
w=Fs->parent_task->pix_width;
h=Fs->parent_task->pix_height;
temps=step_root.next;
while (temps!=&step_root) {
temps1=temps->next;
if (tS-temps->t0>4.0) {
QueRem(temps);
Free(temps);
}
temps=temps1;
}
temps=king_step_root.next;
while (temps!=&king_step_root) {
temps1=temps->next;
if (tS-temps->t0>4.0) {
QueRem(temps);
Free(temps);
}
temps=temps1;
}
not_stopped_cnt=0;
tempp=peasant_root.next;
while (tempp!=&peasant_root) {
if (tempp->stopped) {
if (tempp->door_opened_t0 && tS>tempp->door_opened_t0+1.0) {
tempp->door_opened_t0=0;
tempp->y=tempp->x=-9999;
}
} else {
if (Sqr(tempp->x-w/2)+Sqr(tempp->y-h/2)<20*20) {
tempp->stopped=TRUE;
tempp->door_opened_t0=door_open_t0=tS;
}
for (i=0;i<NUM_TREES;i++) //Hang-out by fire
if (trees[i].fire_frame_index && Sqr(tempp->x-trees[i].x)+Sqr(tempp->y-trees[i].y)<20*20) {
tempp->stopped=TRUE;
break;
}
if (!tempp->stopped) {
Follow(Fs->parent_task,tempp);
tempp->x+=Cos(tempp->é)/100;
tempp->y+=Sin(tempp->é)/100;
if (!(BORDER/2<=tempp->x<w-BORDER/2) || !(BORDER/2<=tempp->y<h-BORDER/2)) {
tempp->é+=ã;
tempp->x+=3*Cos(tempp->é)/100;
tempp->y+=3*Sin(tempp->é)/100;
}
if (!(animate_cnt&511))
StepNew(Fs->parent_task,tempp->x,tempp->y,tempp->é,FALSE);
not_stopped_cnt++;
}
}
tempp=tempp->next;
}
if (!not_stopped_cnt && !tf) {
tf=tS;
music_mute=TRUE;
Snd(2000);Sleep(200);Snd(0);Sleep(100);
if (tf-t0<best_score) {
best_score=tf-t0;
Snd(2000);Sleep(200);Snd(0);Sleep(100);
}
music_mute=FALSE;
}
snow_x+=RandU16%3-1;
snow_y+=1-SignI64(RandU16&3);
Sleep(1);
animate_cnt++;
}
}
U0 BurnTrees()
{
I64 i;
for (i=0;i<NUM_TREES;i++)
if (Sqr(king_x-trees[i].x)+Sqr(king_y-trees[i].y)<10*10)
trees[i].fire_frame_index=1;
}
U0 SongTask(I64)
{
Fs->task_end_cb=&SndTaskEndCB;
MusicSettingsRst;
music_tempo= 2.480;
music_stacatto_factor= 0.902;
while (TRUE) {
Play("3eCCCDCC2qG3eA2G3ABqCC");
Play("eCCCDCC2qG3eA2G3ABqCC");
Play("eGFEDEDqCeA2G3ABqCC");
}
}
U0 Wenceslas()
{
I64 sc;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" BurnTree(,CH_SPACE);"
" Up(,,SC_CURSOR_UP);"
" Down(,,SC_CURSOR_DOWN);"
" Left(,,SC_CURSOR_LEFT);"
" Right(,,SC_CURSOR_RIGHT);"
"}"
);
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
WinMax;
Preempt(OFF);
Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
PopUpOk("
Good King Wenceslas looked out
On the feast of Stephen
When the snow lay round about
Deep and crisp and even
Brightly shone the moon that night
Though the frost was cruel
When a poor man came in sight
Gath'ring winter fuel
\"Hither, page, and stand by me
If thou know'st it, telling
Yonder peasant, who is he?
Where and what his dwelling?\"
\"Sire, he lives a good league hence
Underneath the mountain
Right against the forest fence
By Saint Agnes' fountain.\"
\"Bring me flesh and bring me wine
Bring me pine logs hither
Thou and I will see him dine
When we bear him thither.\"
Page and monarch forth they went
Forth they went together
Through the rude wind's wild lament
And the bitter weather
");
PopUpOk("
\"Sire, the night is darker now
And the wind blows stronger
Fails my heart, I know not how,
I can go no longer.\"
\"Mark my footsteps, my good page
Tread thou in them boldly
Thou shalt find the winter's rage
Freeze thy blood less coldly.\"
In his master's steps he trod
Where the snow lay dinted
Heat was in the very sod
Which the Saint had printed
Therefore, Christian men, be sure
Wealth or rank possessing
Ye who now will bless the poor
Shall yourselves find blessing
");
PopUpOk("
$$PURPLE$$$$TX+CX,\"Winceslas Game\"$$$$FG$$
Start fires by pressing $$GREEN$$<SPACE BAR>$$FG$$
on trees. (Yule logs)
Lead peasants to fires.
");
Init;
Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
WordStat;
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
try {
while (TRUE) {
switch (GetKey(&sc)) {
case '\n':
CleanUp;
Init;
break;
case CH_ESC:
case CH_SHIFT_ESC:
goto ws_done;
case CH_SPACE:
BurnTrees;
break;
case 0:
switch (sc.u8[0]) {
case SC_CURSOR_RIGHT:
if (king_x+KING_STEP<Fs->pix_width-BORDER)
king_x+=KING_STEP;
king_é=0;
StepNew(Fs,king_x,king_y,king_é,TRUE);
break;
case SC_CURSOR_LEFT:
if (king_x-KING_STEP>=BORDER)
king_x-=KING_STEP;
king_é=ã;
StepNew(Fs,king_x,king_y,king_é,TRUE);
break;
case SC_CURSOR_DOWN:
if (king_y+KING_STEP<Fs->pix_height-BORDER)
king_y+=KING_STEP;
king_é=-ã/2;
StepNew(Fs,king_x,king_y,king_é,TRUE);
break;
case SC_CURSOR_UP:
if (king_y-KING_STEP>=BORDER)
king_y-=KING_STEP;
king_é=ã/2;
StepNew(Fs,king_x,king_y,king_é,TRUE);
break;
}
}
}
ws_done:
} catch
PutExcept;
SettingsPop;
MenuPop;
CleanUp;
AcctRegWriteBranch("TempleOS/Wenceslas","F64 best_score=%5.4f;\n",best_score);
}
Wenceslas;
y
þÿÿÿÚÿÿÿ
Êÿÿÿ
þÿÿÿÚÿÿÿ äÿÿÿ
Öÿÿÿ
Ðÿÿÿ
úÿÿÿÖÿÿÿôÿÿÿìÿÿÿ
üÿÿÿØÿÿÿúÿÿÿðÿÿÿ
üÿÿÿðÿÿÿÖÿÿÿ
üÿÿÿÔÿÿÿòÿÿÿæÿÿÿ
ÒÿÿÿöÿÿÿÂÿÿÿ
þÿÿÿÔÿÿÿòÿÿÿ¼ÿÿÿ
þÿÿÿÎÿÿÿ ¼ÿÿÿ
þÿÿÿÔÿÿÿÊÿÿÿ
þÿÿÿØÿÿÿäÿÿÿ
ÚÿÿÿÀÿÿÿ
þÿÿÿÎÿÿÿ´ÿÿÿ
Êÿÿÿªÿÿÿ
ÿÿÿøÿÿÿÈÿÿÿ
²ÿÿÿ¬ÿÿÿ
Æÿÿÿ
ÿÿÿ
Ìÿÿÿ Ìÿÿÿ
üÿÿÿÔÿÿÿèÿÿÿÚÿÿÿ
Öÿÿÿ*
ðÿÿÿüÿÿÿ
ðÿÿÿ
ðÿÿÿèÿÿÿ
þÿÿÿòÿÿÿüÿÿÿæÿÿÿ
þÿÿÿæÿÿÿàÿÿÿ
þÿÿÿèÿÿÿüÿÿÿòÿÿÿ
æÿÿÿðÿÿÿ
þÿÿÿâÿÿÿàÿÿÿ
àÿÿÿÞÿÿÿ
Þÿÿÿâÿÿÿ
ÞÿÿÿÞÿÿÿ
ýÿÿÿäÿÿÿâÿÿÿ
þÿÿÿäÿÿÿüÿÿÿèÿÿÿ
üÿÿÿèÿÿÿüÿÿÿòÿÿÿ
äÿÿÿêÿÿÿ
æÿÿÿþÿÿÿîÿÿÿ
ìÿÿÿòÿÿÿx
þÿÿÿèÿÿÿüÿÿÿòÿÿÿ
ðÿÿÿèÿÿÿ
ðÿÿÿüÿÿÿ
ðÿÿÿ
þÿÿÿòÿÿÿüÿÿÿæÿÿÿ
þÿÿÿæÿÿÿàÿÿÿ
æÿÿÿðÿÿÿã
öÿÿÿðÿÿÿ
øÿÿÿ
ôÿÿÿ
ðÿÿÿòÿÿÿ
îÿÿÿ
êÿÿÿ
öÿÿÿæÿÿÿ
úÿÿÿæÿÿÿöÿÿÿèÿÿÿ
øÿÿÿæÿÿÿ
æÿÿÿ
øÿÿÿîÿÿÿ
þÿÿÿòÿÿÿ 
þÿÿÿöÿÿÿ
ôÿÿÿîÿÿÿ
ðÿÿÿ
ðÿÿÿþÿÿÿ
üÿÿÿþÿÿÿäÿÿÿ
þÿÿÿäÿÿÿîÿÿÿ
äÿÿÿöÿÿÿöÿÿÿ
öÿÿÿðÿÿÿøÿÿÿ
üÿÿÿüÿÿÿðÿÿÿ
ðÿÿÿøÿÿÿ
úÿÿÿ
þÿÿÿúÿÿÿúÿÿÿ
ðÿÿÿüÿÿÿ
úÿÿÿ
üÿÿÿ
üÿÿÿøÿÿÿ
úÿÿÿøÿÿÿúÿÿÿðÿÿÿ
òÿÿÿìÿÿÿô
öÿÿÿðÿÿÿ
øÿÿÿ
ôÿÿÿ
ðÿÿÿòÿÿÿ
îÿÿÿ
êÿÿÿ
öÿÿÿæÿÿÿ
úÿÿÿæÿÿÿöÿÿÿèÿÿÿ
øÿÿÿæÿÿÿ
æÿÿÿ
øÿÿÿîÿÿÿ
þÿÿÿòÿÿÿ 
þÿÿÿöÿÿÿ
ôÿÿÿîÿÿÿ
äÿÿÿ
úÿÿÿâÿÿÿúÿÿÿ
èÿÿÿúÿÿÿöÿÿÿ
òÿÿÿîÿÿÿöÿÿÿúÿÿÿ
öÿÿÿøÿÿÿðÿÿÿ
öÿÿÿäÿÿÿôÿÿÿôÿÿÿ
üÿÿÿêÿÿÿþÿÿÿþÿÿÿ
üÿÿÿôÿÿÿ
ôÿÿÿöÿÿÿ
òÿÿÿâÿÿÿ
þÿÿÿ
úÿÿÿ
öÿÿÿ
òÿÿÿüÿÿÿ
øÿÿÿðÿÿÿøÿÿÿ
ôÿÿÿ
üÿÿÿÒbŸžÎÿÿÿhÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLine truncated
+173
View File
@@ -0,0 +1,173 @@
#define NUM_BALLS 7
#define NUM_SPRINGS 3
#define STRETCH 500.0
#define GRAVITY 50.0 //not really gravity
#define BALL_RADIUS 5
#define BASE_SIZE 10
CMass balls[NUM_BALLS];
CSpring springs[NUM_SPRINGS];
F64 collision_t;
U0 DrawIt(CTask *task,CDC *dc)
{
I64 i,
cx=task->pix_width>>1,
cy=task->pix_height>>1;
Bool snd_on=FALSE;
dc->color=BLACK;
GrPrint(dc,0,0,"Protect your base.");
GrRect(dc,cx-BASE_SIZE,cy-BASE_SIZE,BASE_SIZE*2,BASE_SIZE*2);
dc->color=CYAN;
GrRect(dc,cx-BASE_SIZE+2,cy-BASE_SIZE+2,BASE_SIZE*2-4,BASE_SIZE*2-4);
dc->color=YELLOW;
GrLine(dc,balls[0].x,balls[0].y,
ipx-task->pix_left-task->scroll_x,
ipy-task->pix_top-task->scroll_y);
for (i=0;i<NUM_SPRINGS;i++)
GrLine(dc,springs[i].end1->x,springs[i].end1->y,
springs[i].end2->x,springs[i].end2->y);
dc->color=LTCYAN;
GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);
GrFloodFill(dc,balls[0].x,balls[0].y,TRUE);
dc->color=BLACK;
GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);
for (i=1;i<NUM_BALLS;i++) {
dc->color=LTPURPLE;
GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
GrFloodFill(dc,balls[i].x,balls[i].y,TRUE);
if (cx-BASE_SIZE-BALL_RADIUS<=balls[i].x<=cx+BASE_SIZE+BALL_RADIUS &&
cy-BASE_SIZE-BALL_RADIUS<=balls[i].y<=cy+BASE_SIZE+BALL_RADIUS)
snd_on=TRUE;
dc->color=BLACK;
GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
}
if (snd_on)
Snd(1000);
else
Snd(0);
}
U0 MyDerivative(CMathODE *ode,F64 t,COrder2D3 *,COrder2D3 *)
{
I64 i,j;
F64 d,dd;
CD3 p,p2;
CTask *task=ode->win_task;
D3SubEqu(D3Equ(&p2,ipx-task->pix_left-task->scroll_x,ipy-task->pix_top-task->scroll_y,0),
&balls[0].state->x);
D3AddEqu(&balls[0].DstateDt->DxDt,D3MulEqu(&p2,STRETCH));
D3Equ(&p2,task->pix_width>>1,task->pix_height>>1,0);
for (i=1;i<NUM_BALLS;i++) {
D3Sub(&p2,&balls[i].state->x,&p);
if (d=D3Norm(&p)) {
//Gravity would be /(d*d*d), but that's too exponential.
D3MulEqu(&p,GRAVITY/d);
D3AddEqu(&balls[i].DstateDt->DxDt,&p);
}
}
for (i=0;i<NUM_BALLS;i++)
for (j=i+1;j<NUM_BALLS;j++) {
D3Sub(&balls[j].state->x,&balls[i].state->x,&p);
dd=D3SqrNorm(&p);
if (dd<=(2*BALL_RADIUS)*(2*BALL_RADIUS)) {
if (t-collision_t>0.05) {
Noise(50,5000,6000);
collision_t=t;
}
d=Sqrt(dd)+0.0001;
dd=10.0*Sqr(Sqr((2*BALL_RADIUS)*(2*BALL_RADIUS)-dd));
D3MulEqu(&p,dd/d);
D3AddEqu(&balls[j].DstateDt->DxDt,&p);
D3SubEqu(&balls[i].DstateDt->DxDt,&p);
}
}
d=balls[0].state->x;
if (d-BALL_RADIUS<0)
balls[0].DstateDt->DxDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
if (d+BALL_RADIUS>task->pix_width)
balls[0].DstateDt->DxDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_width)));
d=balls[0].state->y;
if (d-BALL_RADIUS<0)
balls[0].DstateDt->DyDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
if (d+BALL_RADIUS>task->pix_height)
balls[0].DstateDt->DyDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_height)));
}
U0 Whap()
{
I64 i;
CMathODE *ode=ODENew(0,1e-2,ODEF_HAS_MASSES);
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
WinMax;
WordStat;
Preempt(OFF);
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
);
ode->derivative=&MyDerivative;
ode->drag_v2=0.002;
ode->drag_v3=0.00001;
ode->acceleration_limit=5e3;
MemSet(balls,0,NUM_BALLS*sizeof(CMass));
D3Equ(&balls[0].x,100,100,0);
for (i=1;i<NUM_BALLS;i++)
D3Equ(&balls[i].x,
RandI16%500+Fs->pix_width>>1,RandI16%500+Fs->pix_height>>1,0);
balls[0].x=ipx-Fs->pix_left-Fs->scroll_x;
balls[0].y=ipy-Fs->pix_top-Fs->scroll_y;
for (i=0;i<NUM_BALLS;i++) {
balls[i].mass=1.0;
balls[i].drag_profile_factor=1.0;
QueIns(&balls[i],ode->last_mass);
}
balls[2].x=balls[1].x+15;
balls[2].y=balls[1].y;
balls[3].x=balls[1].x;
balls[3].y=balls[1].y+15;
MemSet(springs,0,NUM_SPRINGS*sizeof(CSpring));
springs[0].end1=&balls[1];
springs[0].end2=&balls[2];
springs[0].rest_len=15;
springs[0].const=10000;
QueIns(&springs[0],ode->last_spring);
springs[1].end1=&balls[1];
springs[1].end2=&balls[3];
springs[1].rest_len=15;
springs[1].const=10000;
QueIns(&springs[1],ode->last_spring);
springs[2].end1=&balls[2];
springs[2].end2=&balls[3];
springs[2].rest_len=sqrt2*15;
springs[2].const=10000;
QueIns(&springs[2],ode->last_spring);
collision_t=0;
QueIns(ode,Fs->last_ode);
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
GetChar;
SettingsPop;
QueRem(ode);
ODEDel(ode);
MenuPop;
}
Whap;
Binary file not shown.
Binary file not shown.