1276 lines
104 KiB
HolyC
Executable File
1276 lines
104 KiB
HolyC
Executable File
RegDft("TempleOS/Titanium","I64 best_score=0;\n");
|
||
RegExe("TempleOS/Titanium");
|
||
|
||
#define MAP_HEIGHT 4096
|
||
|
||
#define B_LEN 10
|
||
#define B_SPEED 5
|
||
#define B_NUM 128
|
||
class Bullet
|
||
{
|
||
I64 x,y,dx,dy,dx2,dy2;
|
||
Bool dead,missile,pad[6];
|
||
} b[B_NUM];
|
||
I64 bullets_fired,missile_bmp;
|
||
|
||
I64 x,y,dx,dy,finish_line;
|
||
F64 é,t0,tf,snd_timeout;
|
||
|
||
#define PHASES_GROUPS 8
|
||
#define HACK_DIST 5
|
||
|
||
#define U_ENEMY_NUM (PHASES_GROUPS*64)
|
||
#define U_FRIENDLY_NUM (PHASES_GROUPS*16)
|
||
#define U_NUM (U_FRIENDLY_NUM+U_ENEMY_NUM)
|
||
class Unit
|
||
{
|
||
I64 x,y,best_dd;
|
||
F64 é,phase;
|
||
Bool friendly,dead,tank,CIA,pad[4];
|
||
} u[U_NUM];
|
||
|
||
#define ET_MAN 0
|
||
#define ET_TANK 1
|
||
#define ET_MISSILE 2
|
||
#define ET_BUILDING 3
|
||
#define E_NUM 512
|
||
class Explosion
|
||
{
|
||
I64 x,y,num,type;
|
||
F64 t0,tf;
|
||
Bool dead,pad[7];
|
||
} e[E_NUM];
|
||
|
||
I64 total_score,friendly_fire,enemy_by_friendly,friendly_left,enemy_left,
|
||
main_loop_pass;
|
||
Bool game_over;
|
||
$BG,14$
|
||
|
||
|
||
|
||
|
||
$SP,"<1>",BI=1$
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<2>",BI=2$
|
||
|
||
$SP,"<3>",BI=3$
|
||
|
||
|
||
|
||
|
||
$SP,"<4>",BI=4$
|
||
|
||
|
||
|
||
$SP,"<5>",BI=5$
|
||
|
||
|
||
|
||
$SP,"<6>",BI=6$
|
||
|
||
|
||
|
||
U8 *friendly_imgs[4]={$IB,"<5>",BI=5$,$IB,"<4>",BI=4$,$IB,"<5>",BI=5$,$IB,"<6>",BI=6$};
|
||
|
||
|
||
|
||
|
||
$SP,"<7>",BI=7$
|
||
|
||
|
||
|
||
$SP,"<8>",BI=8$
|
||
|
||
|
||
|
||
$SP,"<9>",BI=9$
|
||
|
||
|
||
|
||
U8 *CIA_neeger_imgs[4]={$IB,"<8>",BI=8$,$IB,"<7>",BI=7$,$IB,"<8>",BI=8$,$IB,"<9>",BI=9$};
|
||
|
||
|
||
|
||
|
||
$SP,"<10>",BI=10$
|
||
|
||
|
||
|
||
|
||
$SP,"<11>",BI=11$
|
||
|
||
|
||
|
||
|
||
$SP,"<12>",BI=12$
|
||
|
||
|
||
|
||
|
||
U8 *friendly_hacking_imgs[4]={$IB,"<10>",BI=10$,$IB,"<11>",BI=11$,$IB,"<10>",BI=10$,$IB,"<12>",BI=12$};
|
||
|
||
|
||
|
||
|
||
$SP,"<13>",BI=13$
|
||
|
||
|
||
|
||
$SP,"<14>",BI=14$
|
||
|
||
|
||
|
||
$SP,"<15>",BI=15$
|
||
|
||
|
||
|
||
U8 *enemy_imgs[4]={$IB,"<14>",BI=14$,$IB,"<13>",BI=13$,$IB,"<14>",BI=14$,$IB,"<15>",BI=15$};
|
||
|
||
|
||
|
||
|
||
$SP,"<16>",BI=16$
|
||
|
||
|
||
|
||
|
||
$SP,"<17>",BI=17$
|
||
|
||
|
||
|
||
|
||
$SP,"<18>",BI=18$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<19>",BI=19$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
U8 *enemy_hacking_imgs[4]={$IB,"<17>",BI=17$,$IB,"<16>",BI=16$,$IB,"<17>",BI=17$,$IB,"<18>",BI=18$};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<20>",BI=20$
|
||
|
||
|
||
|
||
|
||
$SP,"<21>",BI=21$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<22>",BI=22$
|
||
|
||
|
||
|
||
|
||
$SP,"<23>",BI=23$
|
||
|
||
|
||
|
||
|
||
$BG$
|
||
#define LS_APTS_NUM 20
|
||
#define LS_MOUNTAINS_NUM 3
|
||
#define LS_NUM 128
|
||
class LandScapeItem
|
||
{
|
||
I64 x,y;
|
||
U8 *img;
|
||
} ls[LS_NUM];
|
||
|
||
#define LS_TYPES 4
|
||
U8 *landscape_imgs[LS_TYPES]=
|
||
{$IB,"<20>",BI=20$,$IB,"<21>",BI=21$,$IB,"<22>",BI=22$,$IB,"<23>",BI=23$};
|
||
|
||
U0 ExplosionDraw(CDC *dc,Explosion *tmpe,I64 y)
|
||
{
|
||
I64 i,n1,n2,n3,n4,n5;
|
||
F64 t=(tS-tmpe->t0)/(tmpe->tf-tmpe->t0);
|
||
Seed(tmpe->num+1);
|
||
|
||
switch (tmpe->type) {
|
||
case ET_MAN: n1=8; n2=0; n3=0; n4=18; n5=28; break;
|
||
case ET_TANK: n1=64; n2=14; n3=24; n4=60; n5=90; break;
|
||
case ET_MISSILE: n1=128; n2=30; n3=60; n4=100; n5=200; break;
|
||
case ET_BUILDING: n1=128; n2=80; n3=80; n4=200; n5=300; break;
|
||
}
|
||
for (i=0;i<n1;i++) {
|
||
if (i&2)
|
||
switch (tmpe->type) {
|
||
case ET_MAN:
|
||
if (i&1)
|
||
dc->color=WHITE;
|
||
else
|
||
dc->color=LTGRAY;
|
||
break;
|
||
case ET_MISSILE:
|
||
if (i&1) {
|
||
if (i&4)
|
||
dc->color=RED;
|
||
else
|
||
dc->color=DKGRAY;
|
||
} else
|
||
dc->color=YELLOW;
|
||
break;
|
||
case ET_TANK:
|
||
if (i&1) {
|
||
if (i&4)
|
||
dc->color=RED;
|
||
else
|
||
dc->color=DKGRAY;
|
||
} else
|
||
dc->color=LTRED;
|
||
break;
|
||
case ET_BUILDING:
|
||
if (i&1) {
|
||
if (i&4)
|
||
dc->color=BLACK;
|
||
else
|
||
dc->color=DKGRAY;
|
||
} else
|
||
dc->color=LTGRAY;
|
||
break;
|
||
}
|
||
else if (i&1)
|
||
dc->color=WHITE;
|
||
else
|
||
dc->color=LTGRAY;
|
||
GrLine(dc,tmpe->x+n2*(Rand-.5),y+n3/2*Rand,
|
||
tmpe->x+n4*t*(Rand-.5),y-n5/2*t*Rand);
|
||
}
|
||
}
|
||
|
||
I64 mp_not_done_flags;
|
||
U0 MPMenDraw(CDC *dc2)
|
||
{
|
||
CTask *task=dc2->win_task;
|
||
CDC *dc=DCAlias(dc2,task);
|
||
I64 i,r[16],lo=Gs->num*U_NUM/mp_cnt,hi=(Gs->num+1)*U_NUM/mp_cnt,
|
||
yy,phase,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
|
||
Unit *tmpu;
|
||
Explosion *tmpe;
|
||
U8 *tmps,**_tmps;
|
||
F64 tt,ts=tS;
|
||
|
||
for (i=Gs->num;i<E_NUM;i+=mp_cnt) {
|
||
tmpe=&e[i];
|
||
yy=(tmpe->y-scroll_y)&(MAP_HEIGHT-1);
|
||
if (-32<=yy<=task->pix_bottom+32 && !tmpe->dead) {
|
||
ExplosionDraw(dc,tmpe,yy);
|
||
if (tS>tmpe->tf)
|
||
tmpe->dead=TRUE;
|
||
}
|
||
}
|
||
for (i=lo;i<hi;i++) {
|
||
tmpu=&u[i];
|
||
yy=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
|
||
if (-32<=yy<=task->pix_bottom+32) {
|
||
if (!tmpu->dead) {
|
||
Mat4x4IdentEqu(r);
|
||
Mat4x4RotY(r,tmpu->é);
|
||
Mat4x4RotX(r,ã/6);
|
||
Mat4x4Scale(r,0.3);
|
||
if (tmpu->tank)
|
||
Sprite3Mat4x4B(dc,tmpu->x,yy,GR_Z_ALL,$IB,"<19>",BI=19$,r);
|
||
else {
|
||
if (tmpu->best_dd<(2*HACK_DIST)*(2*HACK_DIST)) {//It's neat so times 2
|
||
if (tmpu->friendly)
|
||
_tmps=friendly_hacking_imgs;
|
||
else
|
||
_tmps=enemy_hacking_imgs;
|
||
tt=4*Wrap(tmpu->phase+20*ts,0)/(2*ã);
|
||
} else {
|
||
if (tmpu->friendly) {
|
||
if (tmpu->CIA && Blink)
|
||
_tmps=CIA_neeger_imgs;
|
||
else
|
||
_tmps=friendly_imgs;
|
||
} else
|
||
_tmps=enemy_imgs;
|
||
tt=4*Wrap(tmpu->phase+5*ts,0)/(2*ã);
|
||
}
|
||
phase=tt; tt%=1.0;
|
||
tmps=SpriteInterpolate(tt,_tmps[phase&3],_tmps[(phase+1)&3]);
|
||
Sprite3Mat4x4B(dc,tmpu->x,yy,GR_Z_ALL,tmps,r);
|
||
Free(tmps);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
dc->depth_buf=NULL;
|
||
DCDel(dc);
|
||
LBtr(&mp_not_done_flags,Gs->num);
|
||
Seed; //Return Seth task to timer-based.
|
||
}
|
||
|
||
U0 MissilePos(I64 m,F64 é,I64 *_x,I64 *_y)
|
||
{
|
||
I64 n;
|
||
if (m<2)
|
||
n=-1;
|
||
else
|
||
n=1;
|
||
*_x=x+3.0*Cos(é)-(15.0-(m&1)<<3)*Cos(é-n*ã/2);
|
||
*_y=y+3.0*Sin(é)-(15.0-(m&1)<<3)*Sin(é-n*ã/2);
|
||
}
|
||
|
||
U0 DrawIt(CTask *task,CDC *dc)
|
||
{
|
||
I64 i,m,xx,yy,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
|
||
F64 tt,ts=tS;
|
||
Bullet *tmpb;
|
||
|
||
dc->color=ROPF_DITHER|BROWN<<16|YELLOW;
|
||
GrRect3(dc,0,0,0,dc->width,dc->height);
|
||
|
||
for (i=0;i<LS_NUM;i++) {
|
||
yy=(ls[i].y-scroll_y)&(MAP_HEIGHT-1);
|
||
if (-32<=yy<=task->pix_bottom+32)
|
||
Sprite3(dc,ls[i].x,yy,0,ls[i].img);
|
||
}
|
||
|
||
dc->thick=3;
|
||
dc->color=BROWN;
|
||
GrLine3(dc,0, (finish_line-scroll_y)&(MAP_HEIGHT-1),0,
|
||
GR_WIDTH,(finish_line-scroll_y)&(MAP_HEIGHT-1),0);
|
||
|
||
dc->color=LTGRAY;
|
||
for (i=0,tmpb=b;i<B_NUM;i++,tmpb++)
|
||
if (!tmpb->dead) {
|
||
if (tmpb->missile)
|
||
Sprite3ZB(dc,tmpb->x>>32,tmpb->y>>32,0,$IB,"<2>",BI=2$,ã/2+Arg(tmpb->dx,tmpb->dy));
|
||
else
|
||
GrLine(dc,tmpb->x>>32,tmpb->y>>32,
|
||
(tmpb->x+tmpb->dy*B_LEN)>>32,
|
||
(tmpb->y+tmpb->dx*B_LEN)>>32);
|
||
}
|
||
|
||
DCDepthBufAlloc(dc);
|
||
mp_not_done_flags=1<<mp_cnt-1;
|
||
for (i=0;i<mp_cnt;i++)
|
||
JobQue(&MPMenDraw,dc,i);
|
||
while (mp_not_done_flags)
|
||
Yield;
|
||
Free(dc->depth_buf);
|
||
dc->depth_buf=NULL;
|
||
|
||
for (m=0;m<4;m++)
|
||
if (Bt(&missile_bmp,m)) {
|
||
MissilePos(m,é,&xx,&yy);
|
||
Sprite3ZB(dc,xx,yy,0,$IB,"<3>",BI=3$,é);
|
||
}
|
||
Sprite3ZB(dc,x,y,0,$IB,"<1>",BI=1$,é);
|
||
|
||
if (tf) {
|
||
tt=tf;
|
||
dc->color=RED;
|
||
if (game_over && Blink)
|
||
GrPrint(dc,task->pix_width/2-9*FONT_WIDTH/2,task->pix_height/2,
|
||
"Game Over");
|
||
} else {
|
||
tt=ts;
|
||
if (!enemy_left || !friendly_left)
|
||
game_over=TRUE;
|
||
}
|
||
dc->color=BLACK;
|
||
GrPrint(dc,0,0,"Enemy:%d Friends:%d Friendly Fire:%d Time:%6.2f Bullets:%d",
|
||
enemy_left,friendly_left,friendly_fire,tt-t0,bullets_fired);
|
||
GrPrint(dc,0,8,"Total Score:%,d High Score:%,d",
|
||
total_score,best_score);
|
||
}
|
||
|
||
Explosion *ExplosionNew(I64 x,I64 y)
|
||
{
|
||
I64 i;
|
||
for (i=0;i<E_NUM;i++)
|
||
if (e[i].dead) {
|
||
e[i].x=x;
|
||
e[i].y=y;
|
||
e[i].dead=FALSE;
|
||
return &e[i];
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
U0 ManDie(Unit *tmpu,Bool by_human)
|
||
{
|
||
Explosion *tmpe;
|
||
|
||
tmpu->dead=TRUE;
|
||
if (by_human) {
|
||
if (tmpe=ExplosionNew(tmpu->x,tmpu->y)) {
|
||
tmpe->t0=tS;
|
||
if (tmpu->tank) {
|
||
tmpe->type=ET_TANK;
|
||
tmpe->tf=tmpe->t0+0.40;
|
||
} else {
|
||
tmpe->type=ET_MAN;
|
||
tmpe->tf=tmpe->t0+0.20;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (tmpu->friendly) {
|
||
friendly_left--;
|
||
if (by_human)
|
||
friendly_fire++;
|
||
} else {
|
||
enemy_left--;
|
||
if (!by_human)
|
||
enemy_by_friendly++;
|
||
}
|
||
if (by_human && !snd_timeout) {
|
||
snd_timeout=tS+0.01;
|
||
if (tmpu->friendly)
|
||
Snd(46);
|
||
else
|
||
Snd(22);
|
||
}
|
||
}
|
||
|
||
U0 ExplosionDo(I64 x,I64 y,I64 scroll_y)
|
||
{
|
||
I64 i,x2,y2;
|
||
Explosion *tmpe;
|
||
Unit *tmpu;
|
||
if (tmpe=ExplosionNew(x,y+scroll_y)) {
|
||
tmpe->t0=tS;
|
||
tmpe->type=ET_MISSILE;
|
||
tmpe->tf=tmpe->t0+1.0;
|
||
}
|
||
for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
|
||
if (!tmpu->dead) {
|
||
x2=tmpu->x;
|
||
y2=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
|
||
if (SqrI64(x-x2)+SqrI64(y-y2)<100*100)
|
||
ManDie(tmpu,TRUE);
|
||
}
|
||
}
|
||
for (i=0;i<LS_APTS_NUM;i++) {
|
||
x2=ls[i].x;
|
||
y2=(ls[i].y-scroll_y)&(MAP_HEIGHT-1);
|
||
if (SqrI64(x-x2)+SqrI64(y-y2)<100*100) {
|
||
if (tmpe=ExplosionNew(x2,y2+scroll_y)) {
|
||
tmpe->t0=tS;
|
||
tmpe->type=ET_BUILDING;
|
||
tmpe->tf=tmpe->t0+2.0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
U0 CheckCollisions()
|
||
{
|
||
I64 i,n1,x,y,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
|
||
Unit *tmpu;
|
||
Bullet *tmpb;
|
||
CDC *dc2=DCNew(GR_WIDTH,GR_HEIGHT);
|
||
dc2->color=LTRED;
|
||
for (i=0,tmpb=b;i<B_NUM;i++,tmpb++)
|
||
if (!tmpb->dead && !tmpb->missile) //Bullets not missiles
|
||
GrLine(dc2,tmpb->x>>32,tmpb->y>>32,
|
||
(tmpb->x+tmpb->dx*B_LEN)>>32,
|
||
(tmpb->y+tmpb->dy*B_LEN)>>32);
|
||
|
||
dc2->color =ROP_COLLISION;
|
||
dc2->bkcolor=BLACK;
|
||
for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
|
||
if (!tmpu->dead) {
|
||
x=tmpu->x;
|
||
y=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
|
||
if (0<=x<GR_WIDTH && 0<=y<GR_HEIGHT) {
|
||
dc2->collision_cnt=0;
|
||
GrRect(dc2,x-3,y-9,6,8);
|
||
if (dc2->collision_cnt)
|
||
ManDie(tmpu,TRUE);
|
||
}
|
||
}
|
||
}
|
||
DCDel(dc2);
|
||
|
||
for (i=0,tmpb=b;i<B_NUM;i++,tmpb++)
|
||
if (!tmpb->dead && tmpb->missile) { //Missiles not bullets
|
||
x=tmpb->x>>32;
|
||
y=tmpb->y>>32;
|
||
for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
|
||
if (tmpu->tank)
|
||
n1=16;
|
||
else
|
||
n1=6;
|
||
if (!tmpu->dead && AbsI64(x-tmpu->x-n1)+
|
||
AbsI64(y-(tmpu->y-scroll_y)&(MAP_HEIGHT-1)+n1)<n1<<1) {
|
||
tmpb->dead=TRUE;
|
||
ExplosionDo(x,y,scroll_y);
|
||
}
|
||
}
|
||
if (!tmpb->dead)
|
||
for (i=0;i<LS_APTS_NUM;i++)
|
||
if (2*SqrI64(x-ls[i].x)+
|
||
3*SqrI64(y+35-(ls[i].y-scroll_y)&(MAP_HEIGHT-1))<2*60*60) {
|
||
tmpb->dead=TRUE;
|
||
ExplosionDo(x,y,scroll_y);
|
||
}
|
||
}
|
||
}
|
||
|
||
U0 Init()
|
||
{
|
||
I64 i,xx,yy,scroll_y=MAP_HEIGHT-100;
|
||
Unit *tmpu;
|
||
|
||
snd_timeout=0;
|
||
Snd;
|
||
|
||
total_score=0;
|
||
game_over=FALSE;
|
||
main_loop_pass=0;
|
||
|
||
x=Fs->pix_width>>1;
|
||
y=0.9*Fs->pix_height;
|
||
finish_line=scroll_y+y;
|
||
dx=0;
|
||
dy=0;
|
||
é=-ã/2;
|
||
|
||
for (i=0;i<LS_NUM;i++) {
|
||
ls[i].x=(Fs->pix_width-100)*RandU32/U32_MAX+50;
|
||
ls[i].y=(MAP_HEIGHT-100)*RandU32/U32_MAX+50;
|
||
ls[i].img=landscape_imgs[RandU16%(LS_TYPES-2)];
|
||
}
|
||
|
||
for (i=0;i<LS_APTS_NUM;i++)
|
||
ls[i].img=landscape_imgs[LS_TYPES-1]; //Apartment
|
||
|
||
for (;i<LS_APTS_NUM+LS_MOUNTAINS_NUM;i++)
|
||
ls[i].img=landscape_imgs[LS_TYPES-2]; //mountain
|
||
|
||
MemSet(u,0,sizeof(u));
|
||
for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
|
||
if (i<U_FRIENDLY_NUM) {
|
||
tmpu->friendly=TRUE;
|
||
if (!(i&7)) {
|
||
xx=(Fs->pix_width-200)*RandU32/U32_MAX;
|
||
yy=(MAP_HEIGHT-200)*RandU32/U32_MAX;
|
||
}
|
||
if (!(i&63))
|
||
tmpu->CIA=TRUE;
|
||
else
|
||
tmpu->CIA$PB$=FALSE;
|
||
} else {
|
||
tmpu->friendly=FALSE;
|
||
if (!(i&31)) {
|
||
xx=(Fs->pix_width-200)*RandU32/U32_MAX;
|
||
yy=(MAP_HEIGHT-200)*RandU32/U32_MAX;
|
||
}
|
||
if (!(i&15))
|
||
tmpu->tank=TRUE;
|
||
}
|
||
tmpu->dead=FALSE;
|
||
tmpu->x=xx+64*RandI32/I32_MAX+100;
|
||
tmpu->y=yy+64*RandU32/I32_MAX-64+100;
|
||
tmpu->best_dd=I64_MAX;
|
||
tmpu->é=ã/2;
|
||
tmpu->phase=2*ã*Rand;
|
||
}
|
||
for (i=0;i<B_NUM;i++)
|
||
b[i].dead=TRUE;
|
||
for (i=0;i<E_NUM;i++) {
|
||
e[i].dead=TRUE;
|
||
e[i].num=i;
|
||
}
|
||
friendly_left=U_FRIENDLY_NUM;
|
||
enemy_left =U_ENEMY_NUM;
|
||
enemy_by_friendly=0;
|
||
bullets_fired=0;
|
||
missile_bmp =15;
|
||
friendly_fire=0;
|
||
t0=tS;
|
||
tf=0;
|
||
}
|
||
|
||
U0 FireBullet()
|
||
{
|
||
I64 i,j;
|
||
F64 a;
|
||
Bullet *tmpb;
|
||
for (i=0;i<B_NUM-1;i++)
|
||
if (b[i].dead)
|
||
break;
|
||
tmpb=&b[i];
|
||
|
||
j=x+28.0*Cos(é);
|
||
tmpb->x=j<<32;
|
||
j=y+28.0*Sin(é);
|
||
tmpb->y=j<<32;
|
||
|
||
tmpb->dx2=(B_SPEED*Cos(é)+dx)*0x100000000;
|
||
tmpb->dy2= B_SPEED*Sin(é)*0x100000000;
|
||
a=Arg(tmpb->dx2,tmpb->dy2);
|
||
tmpb->dx=Sin(a)*0x100000000;
|
||
tmpb->dy=Cos(a)*0x100000000;
|
||
bullets_fired++;
|
||
tmpb->dead=FALSE;
|
||
tmpb->missile=FALSE;
|
||
if (!snd_timeout) {
|
||
snd_timeout=tS+0.0005;
|
||
Snd(74);
|
||
}
|
||
}
|
||
|
||
Bool FireMissile(I64 n)
|
||
{
|
||
I64 i,m;
|
||
F64 a;
|
||
Bullet *tmpb;
|
||
Bool res=FALSE;
|
||
|
||
m=n;
|
||
if (Btr(&missile_bmp,++m) || Btr(&missile_bmp,++m))
|
||
res=TRUE;
|
||
|
||
if (res) {
|
||
for (i=0;i<B_NUM-1;i++)
|
||
if (b[i].dead)
|
||
break;
|
||
tmpb=&b[i];
|
||
|
||
MissilePos(m,é,&tmpb->x,&tmpb->y);
|
||
tmpb->x<<=32;
|
||
tmpb->y<<=32;
|
||
|
||
tmpb->dx2=(B_SPEED*Cos(é)+dx)*0x100000000;
|
||
tmpb->dy2= B_SPEED*Sin(é)*0x100000000;
|
||
a=Arg(tmpb->dx2,tmpb->dy2);
|
||
tmpb->dx=Sin(a)*0x100000000;
|
||
tmpb->dy=Cos(a)*0x100000000;
|
||
tmpb->dead=FALSE;
|
||
tmpb->missile=TRUE;
|
||
if (!snd_timeout) {
|
||
snd_timeout=tS+0.0005;
|
||
Snd(74);
|
||
}
|
||
}
|
||
}
|
||
|
||
U0 MenMove(I64 phase_group)
|
||
{
|
||
I64 i,j,dd,best,best_dd;
|
||
for (i=phase_group;i<U_FRIENDLY_NUM;i+=PHASES_GROUPS) {
|
||
if (!u[i].dead) {
|
||
best=U_FRIENDLY_NUM;
|
||
best_dd=I64_MAX;
|
||
for (j=U_FRIENDLY_NUM;j<U_NUM;j++) {
|
||
if (!u[j].dead) {
|
||
dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
|
||
if (dd<best_dd) {
|
||
best_dd=dd;
|
||
best=j;
|
||
}
|
||
}
|
||
}
|
||
u[i].best_dd=best_dd;
|
||
if (best_dd!=I64_MAX) {
|
||
u[i].x+=4*SignI64(u[best].x-u[i].x);
|
||
u[i].y+=4*SignI64(u[best].y-u[i].y);
|
||
u[i].é=Arg(u[best].x-u[i].x,u[best].y-u[i].y);
|
||
}
|
||
}
|
||
}
|
||
for (i=U_FRIENDLY_NUM+phase_group;i<U_NUM;i+=PHASES_GROUPS) {
|
||
if (!u[i].dead) {
|
||
best=0;
|
||
best_dd=I64_MAX;
|
||
for (j=0;j<U_FRIENDLY_NUM;j++) {
|
||
if (!u[j].dead) {
|
||
dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
|
||
if (dd<best_dd) {
|
||
best_dd=dd;
|
||
best=j;
|
||
}
|
||
}
|
||
}
|
||
u[i].best_dd=best_dd;
|
||
if (best_dd!=I64_MAX) {
|
||
u[i].x+=4*SignI64(u[best].x-u[i].x);
|
||
u[i].y+=4*SignI64(u[best].y-u[i].y);
|
||
u[i].é=Arg(u[best].x-u[i].x,u[best].y-u[i].y);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
U0 MenFight(I64 phase_group)
|
||
{
|
||
I64 i,j,dd,best,best_dd;
|
||
for (i=phase_group;i<U_FRIENDLY_NUM;i+=PHASES_GROUPS) {
|
||
if (!u[i].dead) {
|
||
best=U_FRIENDLY_NUM;
|
||
best_dd=I64_MAX;
|
||
for (j=U_FRIENDLY_NUM;j<U_NUM;j++) {
|
||
if (!u[j].dead && u[i].y-u[j].y<8) {
|
||
dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
|
||
if (dd<best_dd) {
|
||
best_dd=dd;
|
||
best=j;
|
||
}
|
||
}
|
||
}
|
||
u[i].best_dd=best_dd;
|
||
if (best_dd<HACK_DIST*HACK_DIST && !(RandU16&1))
|
||
ManDie(&u[best],FALSE);
|
||
}
|
||
}
|
||
for (i=U_FRIENDLY_NUM+phase_group;i<U_NUM;i+=PHASES_GROUPS) {
|
||
if (!u[i].dead) {
|
||
best=0;
|
||
best_dd=I64_MAX;
|
||
for (j=0;j<U_FRIENDLY_NUM;j++) {
|
||
if (!u[j].dead&& u[i].y-u[j].y<8) {
|
||
dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
|
||
if (dd<best_dd) {
|
||
best_dd=dd;
|
||
best=j;
|
||
}
|
||
}
|
||
}
|
||
u[i].best_dd=best_dd;
|
||
if (best_dd<HACK_DIST*HACK_DIST && !(RandU16&1))
|
||
ManDie(&u[best],FALSE);
|
||
}
|
||
}
|
||
}
|
||
|
||
U0 Titanium()
|
||
{
|
||
I64 i,msg_code,ch,sc;
|
||
Bool gun_on;
|
||
|
||
I64 next_update_jiffy;
|
||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||
|
||
MenuPush(
|
||
"File {"
|
||
" Abort(,CH_SHIFT_ESC);"
|
||
" Exit(,CH_ESC);"
|
||
"}"
|
||
"Play {"
|
||
" Restart(,'\n');"
|
||
" Fire(,CH_SPACE);"
|
||
" Left(,,SC_CURSOR_LEFT);"
|
||
" Right(,,SC_CURSOR_RIGHT);"
|
||
" LeftMissile(,,SC_CURSOR_LEFT|SCF_CTRL);"
|
||
" RightMissile(,,SC_CURSOR_RIGHT|SCF_CTRL);"
|
||
"}"
|
||
);
|
||
AutoComplete;
|
||
WinBorder;
|
||
WinMax;
|
||
DocCursor;
|
||
DocClear;
|
||
|
||
"\nScoring:\n"
|
||
"\tEnemy Killed\t\t+3\n"
|
||
"\tEnemy by Friendly\t+5\n"
|
||
"\tFriendly Fire\t\t-100\n"
|
||
"\tBullets Fired\t\t-1\n"
|
||
"\tGame Time\t\t-10 per second\n"
|
||
"\tSurviving Friendlies\t+250\n\n"
|
||
"Sweep side-to-side while shooting, "
|
||
"holding down $$GREEN$$<SPACE>$$FG$$.\n\n";
|
||
PressAKey;
|
||
|
||
Init;
|
||
DocClear;
|
||
Fs->draw_it=&DrawIt;
|
||
|
||
gun_on=FALSE;
|
||
|
||
try {
|
||
while (TRUE) {
|
||
next_update_jiffy=cnts.jiffies+JIFFY_FREQ/100;
|
||
while (msg_code=ScanMsg(&ch,&sc,1<<MSG_KEY_DOWN+1<<MSG_KEY_UP)) {
|
||
switch (msg_code) {
|
||
case MSG_KEY_DOWN:
|
||
switch (ch) {
|
||
case 0:
|
||
switch (sc.u8[0]) {
|
||
case SC_CURSOR_RIGHT:
|
||
if (sc&SCF_CTRL)
|
||
FireMissile(1);
|
||
break;
|
||
case SC_CURSOR_LEFT:
|
||
if (sc&SCF_CTRL)
|
||
FireMissile(-1);
|
||
break;
|
||
}
|
||
break;
|
||
case CH_SHIFT_ESC:
|
||
case CH_ESC:
|
||
goto to_done;
|
||
case '\n':
|
||
Init;
|
||
break;
|
||
case CH_SPACE:
|
||
gun_on=TRUE;
|
||
break;
|
||
}
|
||
break;
|
||
case MSG_KEY_UP:
|
||
if (ch==CH_SPACE)
|
||
gun_on=FALSE;
|
||
else if (sc.u8[0]==SC_CURSOR_RIGHT||sc.u8[0]==SC_CURSOR_LEFT)
|
||
é=-ã/2;
|
||
break;
|
||
}
|
||
}
|
||
|
||
for (i=0;i<B_NUM;i++) {
|
||
if (!b[i].dead) {
|
||
b[i].x+=b[i].dx2;
|
||
b[i].y+=b[i].dy2;
|
||
if (b[i].y<0||b[i].x<0||
|
||
b[i].x>>32>=Fs->pix_width||
|
||
b[i].y>>32>=Fs->pix_height)
|
||
b[i].dead=TRUE;
|
||
}
|
||
}
|
||
|
||
dx=0;
|
||
if (!Bt(kbd.down_bitmap,SC_CTRL)) {
|
||
if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
|
||
é=-ã/2-15.0*ã/180.0;
|
||
dx=-2;
|
||
} else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
|
||
é=-ã/2+15.0*ã/180.0;
|
||
dx=2;
|
||
}
|
||
}
|
||
x+=dx;
|
||
while (x>=Fs->pix_width)
|
||
x-=Fs->pix_width;
|
||
while (x<0)
|
||
x+=Fs->pix_width;
|
||
|
||
//It takes too much CPU do do all these all the time.
|
||
switch [main_loop_pass&7] {
|
||
case 0:
|
||
switch [main_loop_pass>>3&7] {
|
||
case 0:
|
||
if (--y<20)
|
||
game_over=TRUE;
|
||
case 2:
|
||
case 4:
|
||
case 6:
|
||
MenFight(main_loop_pass>>4%PHASES_GROUPS);
|
||
break;
|
||
case 1:
|
||
case 3:
|
||
case 5:
|
||
case 7:
|
||
MenMove (main_loop_pass>>4%PHASES_GROUPS);
|
||
break;
|
||
}
|
||
case 4:
|
||
break;
|
||
case 2:
|
||
case 6:
|
||
if (gun_on)
|
||
FireBullet;
|
||
break;
|
||
case 1:
|
||
case 3:
|
||
case 5:
|
||
case 7:
|
||
CheckCollisions;
|
||
break;
|
||
}
|
||
main_loop_pass++;
|
||
|
||
if (snd_timeout && tS>snd_timeout) {
|
||
snd_timeout=0;
|
||
Snd;
|
||
}
|
||
SleepUntil(next_update_jiffy);
|
||
|
||
total_score=3*(U_ENEMY_NUM-enemy_left)+5*enemy_by_friendly
|
||
-100*friendly_fire-10*(tS-t0)-bullets_fired;
|
||
if (game_over) {
|
||
tf=tS;
|
||
Sleep(750);
|
||
FlushMsgs;
|
||
while (!ScanKey(&ch)&&friendly_left||tS-tf<1.5) {
|
||
total_score+=250;
|
||
Snd(86); Sleep(150);
|
||
Snd; Sleep(50);
|
||
friendly_left--;
|
||
}
|
||
total_score+=250*friendly_left;
|
||
if (total_score>best_score)
|
||
best_score=total_score;
|
||
if (!ch) ch=GetChar(,FALSE);
|
||
if (ch==CH_ESC||ch==CH_SHIFT_ESC)
|
||
goto to_done;
|
||
gun_on=FALSE;
|
||
Init;
|
||
}
|
||
}
|
||
to_done:
|
||
GetMsg(,,1<<MSG_KEY_UP);
|
||
}
|
||
catch
|
||
PutExcept;
|
||
SettingsPop;
|
||
MenuPop;
|
||
RegWrite("TempleOS/Titanium","I64 best_score=%d;\n",best_score);
|
||
}
|
||
|