334 lines
7.2 KiB
Plaintext
334 lines
7.2 KiB
Plaintext
#define p1_color (ROP_OR+GR_LTGREEN)
|
|
#define p2_color (ROP_OR+GR_YELLOW)
|
|
#define jn1_color (ROP_OR+GR_LTGREEN)
|
|
#define jn2_color (ROP_OR+GR_LTBLUE)
|
|
#define enemy_fire_color (ROP_OR+GR_LTBLUE)
|
|
#define friendly_fire_color (ROP_OR+GR_WHITE)
|
|
|
|
GrBitMap *WG_base=GrNew(grbase);
|
|
|
|
$PI,"+",1$
|
|
|
|
U1 *GrTrooper=$IB,"<Trooper Image>",1$;
|
|
|
|
class Trooper
|
|
{
|
|
I8 x,y,dx,dy,fx,fy,att,def,rng,player;
|
|
U8 fire_end_time;
|
|
};
|
|
|
|
#define num_troopers 100
|
|
|
|
Trooper tr[num_troopers<<1];
|
|
U8 cnt1,cnt2;
|
|
I8 jn;
|
|
I8 text_area_size=MulI8(grheight/FONT_HEIGHT,grwidth/FONT_WIDTH);
|
|
|
|
|
|
#define mm_none 1
|
|
#define mm_friendly_firepower 2
|
|
#define mm_laps_time 3
|
|
I8 map_mode=mm_none;
|
|
U2 *map_values;
|
|
|
|
|
|
#define ai_nothing 1
|
|
#define ai_target 2
|
|
#define ai_random 3
|
|
U8 ai;
|
|
|
|
void UpdateMap()
|
|
{
|
|
I8 i;
|
|
for (i=Fs->window_top;i<=Fs->window_bottom;i++) {
|
|
MemCpy(textbase+i*Fs->crt_width+Fs->window_left,
|
|
map_values+i*Fs->crt_width+Fs->window_left,
|
|
Fs->window_right+4-Fs->window_left);
|
|
}
|
|
}
|
|
|
|
void ClearMapValues()
|
|
{
|
|
MemSet(map_values,0,text_area_size*sizeof(U4));
|
|
}
|
|
|
|
void PutFriendlyFirepower()
|
|
{
|
|
I8 i,d,x,y,dx,dy;
|
|
I8 lt=Fs->window_left>>2,rt=Fs->window_right>>2,
|
|
tp=Fs->window_top, bm=Fs->window_bottom;
|
|
U4 *ptr;
|
|
U8 v;
|
|
for (y=0;y<=bm-tp;y++) {
|
|
ptr=map_values+(y+tp)*Fs->crt_width+Fs->window_left;
|
|
for (x=0;x<=rt-lt;x++) {
|
|
v=0;
|
|
for (i=0;i<num_troopers;i++)
|
|
if (tr[i].def>0 && tr[i].fire_end_time<jiffies) {
|
|
dx=(tr[i].x>>16)-(x*FONT_WIDTH+FONT_WIDTH>>1);
|
|
dy=(tr[i].y>>16)-(y*FONT_HEIGHT+FONT_HEIGHT>>1);
|
|
d=dx*dx+dy*dy;
|
|
if (d<tr[i].rng)
|
|
v+=tr[i].att;
|
|
}
|
|
ptr[x]=(v*128 & 0xF000)+CH_SPACE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void DrawTrooper(Trooper *t,U8 color)
|
|
{
|
|
I8 x,y,s,fire_col;
|
|
|
|
if (map_mode==mm_laps_time) {
|
|
x=(t->x+500*t->dx)>>16;
|
|
y=(t->y+500*t->dy)>>16;
|
|
} else {
|
|
x=t->x>>16;
|
|
y=t->y>>16;
|
|
}
|
|
s=t->def;
|
|
|
|
if (s>0) {
|
|
s=s/3;
|
|
WG_base->color=color;
|
|
GrElemsPlot(WG_base,x,y,0,GrTrooper,0);
|
|
if (t->player==0)
|
|
fire_col=friendly_fire_color;
|
|
else
|
|
fire_col=enemy_fire_color;
|
|
if (jiffies<t->fire_end_time) {
|
|
Sound(2000);
|
|
WG_base->color=fire_col;
|
|
GrLine3(WG_base,x,y,0,t->fx>>16,t->fy>>16,0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DrawAllTroopers()
|
|
{
|
|
I1 buf[32];
|
|
I8 i,j,c,x=joycx-Fs->window_pixel_left,y=joycy-Fs->window_pixel_top;
|
|
Ltf *l;
|
|
|
|
GrClear;
|
|
if (map_mode==mm_friendly_firepower)
|
|
PutFriendlyFirepower;
|
|
else {
|
|
ClearWindowText;
|
|
ClearMapValues;
|
|
}
|
|
UpdateMap;
|
|
|
|
l=Fs->aux_ltf;
|
|
LtfUpdateWindowJoin(Fs->aux_ltf,TRUE,FALSE,FALSE,FALSE);
|
|
|
|
Sound(0);
|
|
cnt1=0;
|
|
cnt2=0;
|
|
for (i=0;i<num_troopers;i++)
|
|
if (tr[i].def>0) {
|
|
DrawTrooper(&tr[i],p1_color);
|
|
cnt1++;
|
|
}
|
|
for (i=num_troopers;i<num_troopers<<1;i++)
|
|
if (tr[i].def>0) {
|
|
DrawTrooper(&tr[i],p2_color);
|
|
cnt2++;
|
|
}
|
|
|
|
if (joymax[2]-joymin[2]>joymax[3]-joymin[3])
|
|
jn=DivI8(MulI8(150,joyv[2]-joyrest[2]),joymax[2]-joymin[2]+1);
|
|
else
|
|
jn=DivI8(MulI8(150,joyv[3]-joyrest[3]),joymax[3]-joymin[3]+1);
|
|
if (jn>0)
|
|
c=jn1_color;
|
|
else
|
|
c=jn2_color;
|
|
j=AbsI8(jn);
|
|
WG_base->color=c;
|
|
GrLine3(WG_base,x-jn,y-jn,0,x+jn,y-jn,0);
|
|
GrLine3(WG_base,x+jn,y-jn,0,x+jn,y+jn,0);
|
|
GrLine3(WG_base,x+jn,y+jn,0,x-jn,y+jn,0);
|
|
GrLine3(WG_base,x-jn,y+jn,0,x-jn,y-jn,0);
|
|
SPrintF(buf,"%03d %03d",cnt1,cnt2);
|
|
PlotWindowString(buf,WHITE,0,0);
|
|
}
|
|
|
|
I8 targets[10];
|
|
void InitTroopers()
|
|
{
|
|
I8 i,j,dx,dy;
|
|
Trooper *t;
|
|
for (i=0;i<10;i++) {
|
|
targets[i]=ModU8(RandU2,num_troopers);
|
|
dx=RandU2-0x8000;
|
|
dy=RandU2-0x8000;
|
|
for (j=0;j<10;j++) {
|
|
t=&tr[i*10+j];
|
|
t->x=(grwidth-100-i*10)<<16;
|
|
t->y=(grheight>>1-50+j*10)<<16;
|
|
t->dx=0;
|
|
t->dy=0;
|
|
t->fire_end_time=jiffies;
|
|
t->att=3;
|
|
t->def=10;
|
|
t->rng=50*50;
|
|
t->player=0;
|
|
t=&tr[i*10+j+num_troopers];
|
|
t->x=(100+i*10)<<16;
|
|
t->y=(grheight>>1-50+j*10)<<16;
|
|
t->dx=0;
|
|
t->dy=0;
|
|
if (ai==ai_random) {
|
|
t->dx=dx;
|
|
t->dy=dy;
|
|
}
|
|
t->fire_end_time=jiffies;
|
|
t->att=3;
|
|
t->def=10;
|
|
t->rng=50*50;
|
|
t->player=1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void DoAiTarget()
|
|
{
|
|
I8 i,j;
|
|
Trooper *t,*t2;
|
|
for (i=0;i<10;i++) {
|
|
t2=&tr[targets[i]];
|
|
for (j=0;j<10;j++) {
|
|
t=&tr[i*10+j+num_troopers];
|
|
t->dx=(t2->x-t->x)>>11;
|
|
t->dy=(t2->y-t->y)>>11;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void UpdatePositions()
|
|
{
|
|
I8 i;
|
|
Trooper *t;
|
|
for (i=0;i<num_troopers<<1;i++) {
|
|
t=&tr[i];
|
|
t->x+=t->dx;
|
|
if (t->x>=grwidth<<16) t->x-=grwidth<<16;
|
|
if (t->x<0) t->x+=grwidth<<16;
|
|
t->y+=t->dy;
|
|
if (t->y>=grheight<<16) t->y-=grheight<<16;
|
|
if (t->y<0) t->y+=grheight<<16;
|
|
}
|
|
}
|
|
|
|
void ResolveFiring()
|
|
{
|
|
I8 i,j,d,dx,dy;
|
|
for (i=0;i<num_troopers;i++)
|
|
for (j=num_troopers;j<num_troopers<<1;j++) {
|
|
if (tr[i].def>0 && tr[j].def>0) {
|
|
dx=(tr[i].x-tr[j].x)>>16;
|
|
dy=(tr[i].y-tr[j].y)>>16;
|
|
d=dx*dx+dy*dy;
|
|
if (d<tr[i].rng && tr[i].fire_end_time<jiffies) {
|
|
tr[i].fire_end_time=jiffies+JIFFY_FREQ>>3;
|
|
tr[i].fx=tr[j].x;
|
|
tr[i].fy=tr[j].y;
|
|
tr[j].def=tr[j].def-tr[i].att;
|
|
}
|
|
if (d<tr[j].rng && tr[j].fire_end_time<jiffies) {
|
|
tr[j].fire_end_time=jiffies+JIFFY_FREQ>>3;
|
|
tr[j].fx=tr[i].x;
|
|
tr[j].fy=tr[i].y;
|
|
tr[i].def=tr[i].def-tr[j].att;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UpdateVelocities()
|
|
{
|
|
I8 i,x=joycx-Fs->window_pixel_left,y=joycy-Fs->window_pixel_top,dx,dy,d;
|
|
Trooper *t;
|
|
if (joyb[0]) {
|
|
for (i=0;i<num_troopers;i++) {
|
|
t=&tr[i];
|
|
dx=(x-(t->x>>16));
|
|
dy=(y-(t->y>>16));
|
|
d=dx*dx+dy*dy+1;
|
|
dx=DivI8(jn<<13*dx,d);
|
|
dy=DivI8(jn<<13*dy,d);
|
|
t->dx=t->dx-dx;
|
|
t->dy=t->dy-dy;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void WarGame()
|
|
{
|
|
I8 ch=0;
|
|
U8 sc=0,ms=0,old_ip=ip_pointer_type,
|
|
old_update_window=Fs->update_window;
|
|
Ltf *m;
|
|
BoolU4 old_menu=AssignBit(&Fs->crt_flags,CRTf_HAS_MENU,1);
|
|
|
|
MaximizeWindow;
|
|
|
|
ip_pointer_type=IP_JOYSTICK0;
|
|
LoadJoystickCalibration;
|
|
map_values=MAlloc(text_area_size*sizeof(U4));
|
|
|
|
CursorOff;
|
|
m=LtfRead("::/LT/APPS/WARGAME.MUZ");
|
|
|
|
ClearWindowText;
|
|
ClearMapValues;
|
|
rnd_SEED=jiffies*0x654654;
|
|
Fs->update_window=&DrawAllTroopers;
|
|
while (ms!=101 && ch!=CH_ESC && ch!=CH_CTRLQ) {
|
|
ch=0;ms=0;
|
|
ai=ModU8(RandU2,3)+1;
|
|
InitTroopers();
|
|
while (ch!=CH_ESC && ch!=CH_CR && ch!=CH_SPACE && ch!=CH_CTRLQ && ms!=101 && ms!=100) {
|
|
RandU2;
|
|
ms=0;
|
|
if (ScanChar(&sc,&ch)) {
|
|
if (sc&0xFF==SC_GUI) {
|
|
GrClear;
|
|
ms=DoMenu(m);
|
|
}
|
|
if (ms==1 || ch=='1')
|
|
map_mode=mm_none;
|
|
else if (ms==2 || ch=='2')
|
|
map_mode=mm_friendly_firepower;
|
|
else if (ms==3 || ch=='3')
|
|
map_mode=mm_laps_time;
|
|
}
|
|
Sleep(40);
|
|
if (ai==ai_target)
|
|
DoAiTarget;
|
|
UpdateVelocities;
|
|
UpdatePositions;
|
|
ResolveFiring;
|
|
}
|
|
}
|
|
GrClear;
|
|
CursorOn;
|
|
Sound(0);
|
|
|
|
LtfDel(m);
|
|
Fs->update_window=old_update_window;
|
|
Free(map_values);
|
|
ip_pointer_type=old_ip;
|
|
AssignBit(&Fs->crt_flags,CRTf_HAS_MENU,old_menu);
|
|
LtfBottom(Fs->cur_ltf);
|
|
Auto("\r\r");
|
|
}
|
|
|
|
WarGame;
|
|
|