home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
games
/
table
/
stlcsrsm
/
cel2.c
next >
Wrap
C/C++ Source or Header
|
1986-12-07
|
33KB
|
1,611 lines
#include <stdio.h>
#include <osbind.h>
#include <obdefs.h>
/* Celestial Caesarism - Sept., 1986 - Jack B. Hardy */
int contrl[12],intin[128],ptsin[128],intout[128],ptsout[128],
numships[9][20];
int handle,planets,explored,score,drive,
port_state,hi_mask=0xF00,lo_mask=0x00FF,ch_enable=7,
wr_command=128,rd_command=0,volume=1,
cha_lo=0,cha_hi=1,chb_lo=2,chb_hi=3,cha_vol=8,chb_vol=9;
short contrl_grid[9][20],area_kn[9][20],a_grid[9][20],
industry[9][20],atari_xy[2];
short numplayers,bit_player,turn_num,maxturns,vis_ships,limit_pro,atari;
long f_length=3600;
char player[4][16],buffer[3600],
message1[]="Show Area Known and Controlled by Fleet Admiral ",
a_orders[]="Orders From Fleet Admiral ",
alert0[]="[3][ Celestial Caesarism | Requires Medium Resolution | ]\
[ RESTART ]",
path[]="A:\*.GAM\0",io_file[]="CELESTIA.GAM\0";
struct record{
int eta;
int owner;
int shipsent;
int xs;
int ys;
int xf;
int yf;
};
struct record orders[300];
extern double giaccess();
main()
{
int dum,dum2,rez;
appl_init();
handle=graf_handle(&dum,&dum2,&dum,&dum2);
init_vwk();
color_reg(1,1000,900,0);
color_reg(0,100,100,300);
v_hide_c(handle);
v_clrwk(handle);
rez=Getrez();
if (rez!=1)
end_prg();
else
start_prg();
color_reg(0,1000,1000,1000);
color_reg(1,0,0,0);
v_clsvwk(handle);
appl_exit();
}
/* Open work station */
init_vwk()
{
int i,l_intin[11],l_intout[57];
for (i=0; i<10;l_intin[i++]=1);
l_intin[10]=2;
i=v_opnvwk(l_intin,&handle,l_intout);
Giaccess(volume,cha_vol+wr_command);
Giaccess(volume,chb_vol+wr_command);
port_state=Giaccess(port_state,ch_enable+rd_command);
Giaccess(60,ch_enable+wr_command);
Giaccess(port_state,ch_enable+wr_command);
}
/* Change color register */
color_reg(reg,r,g,b)
int reg,r,g,b;
{
int rgb_in[3];
rgb_in[0]=r;
rgb_in[1]=g;
rgb_in[2]=b;
vs_color(handle,reg,rgb_in);
}
/* End program if not medium resolution */
end_prg()
{
v_show_c(handle,0);
form_alert(1,alert0);
}
/* Delay loop */
wait(time)
long time;
{
long length=0L;
while(length<time) ++length;
}
/* The main program loop */
start_prg()
{
int i,x,y,stat,tot_ships,tot_planets,a_ct,save_stat,load_stat,but=0;
short t=0,quit=0;
char message[70];
save_stat= -1;
atari= -1;
title();
load_stat=load_game();
if(load_stat == -1)
{
get_info();
load_grid();
}
color_reg(0,0,0,300);
while(turn_num<maxturns)
{
for(i=0; i<=numplayers; i++)
{
v_hide_c(handle);
v_clrwk(handle);
draw_grid();
draw_but(10,0,629,14);
strcpy(message,message1);
strcat(message,player[i]);
graf_mouse(3,0);
v_show_c(handle,0);
a_ct=30;
but=0;
while(but==0)
{
text1(message,t);
vq_mouse(handle,&stat,&x,&y);
if(y<14) but=stat;
wait(1000L);
t=t^1;
a_ct--;
if((atari==i)&&(a_ct==0)) but=1;
}
if(atari==i) a_play(i); /* Let Atari play automatically */
else /* Else collect information from human player */
{
v_hide_c(handle);
vsl_color(handle,WHITE);
draw_but(10,0,629,14);
vsl_color(handle,BLACK);
display_grid(i);
vs_curaddress(handle,1,9);
printf(" Status Report For Fleet Admiral %s. ",player[i]);
count(&tot_ships,&tot_planets);
vs_curaddress(handle,2,2);
printf("Total Ships = %3d ~~ Total Planets = %2d ~~ ",tot_ships,tot_planets);
printf("Known Area = %3d ~~ Score = %5d",explored,score);
if(tot_ships==0) /* If player lost all ships skip turn */
{
vs_curaddress(handle,23,30);
puts("\007");
puts("No Ships Available!!");
wait(400000);
break;
}
draw_l_box(1,1,10,166,630,176);
find_orders();
v_rvoff(handle);
}
}
v_hide_c(handle);
v_clrwk(handle);
draw_grid();
draw_but(10,0,629,14);
vst_effects(handle,0);
v_gtext(handle,128,10,"Movement and Battle Phase - Press Button to Begin");
vs_curaddress(handle,24,36);
turn_num++;
printf("Turn # %d",turn_num);
but=0;
while(but==0) vq_mouse(handle,&but,&x,&y);
erase_line();
move_players();
pack_orders();
add_industry();
if(turn_num%5==0) show_status();
vs_curaddress(handle,24,9);
v_rvon(handle);
puts("Press Left Button to Continue - Right Button to Save/Quit Game");
v_rvoff(handle);
but=0;
while(but==0) vq_mouse(handle,&but,&x,&y);
if(turn_num%5==0)
{
color_reg(0,0,0,300);
color_reg(1,1000,900,0);
}
if(but==2)
{
save_stat=save_game();
if(save_stat>-1) turn_num=maxturns;
}
}
if(save_stat== -1) final_show();
}
/* Count players Ships / Planets */
count(tot_ships,tot_planets)
int *tot_ships,*tot_planets;
{
int row,column,ships,planets;
explored=0;
score=0;
ships=0;
planets=0;
for(row=0; row<=8; row++)
for(column=0; column<=19; column++)
if((area_kn[row][column]&bit_player)==bit_player)
{
explored++;
score+=50;
if((contrl_grid[row][column]&bit_player)==bit_player)
{
score+=numships[row][column]*10;
ships+=numships[row][column];
if((contrl_grid[row][column]&16)==16)
{
score+=500;
planets++;
}
}
}
*tot_ships=ships;
*tot_planets=planets;
}
/* Display message in form specified */
text1(message,t)
char message[70];
short int t;
{
vst_effects(handle,t);
vst_color(handle,GREEN);
v_gtext(handle,80,10,message);
}
/* Display title screen */
title()
{
int i;
vst_effects(handle,16);
char_height(24);
vst_color(handle,BLACK);
v_gtext(handle,156,56,"Celestial Caesarism");
vst_effects(handle,0);
vst_color(handle,RED);
char_height(12);
for(i=432; i>=216; i-=8) v_gtext(handle,i,80,"by Jack Hardy ");
vst_color(handle,BLACK);
char_height(6);
for(i=0; i<=280; i+=4) v_gtext(handle,i,96," \275 1986");
}
/* Get player names - etc. */
get_info()
{
char number,yn,ch,name[140];
int i,in,fill,xy[2];
while(yn!='Y' && yn!='y')
{
vst_color(handle,GREEN);
vs_curaddress(handle,14,1);
v_eeos(handle);
v_gtext(handle,208,110," How many players? (1 - 4) ");
vsin_mode(handle,4,1);
number='0';
while(number<'1' || number>'4') vrq_string(handle,1,0,xy,&number);
vs_curaddress(handle,14,55);
printf("%c",number);
vst_color(handle,BLACK);
numplayers=number-49;
vs_curaddress(handle,16,1);
v_rvon(handle);
puts(" Please limit name to 15 characters ");
v_rvoff(handle);
for (i=0; i<=numplayers; i++)
{
in=0;
for(fill=0; fill<=139; fill++) name[fill]='\000';
printf("Enter name of player #%d => ",i+1);
while((vrq_string(handle,1,0,xy,&ch))!=0)
{
if(ch=='\010')
{
in--;
vs_curaddress(handle,17+i,28+in);
v_eeol(handle);
}
else if(ch=='\177')
{
in=0;
for(fill=0; fill<=139; fill++) name[fill]='\000';
vs_curaddress(handle,17+i,28);
v_eeol(handle);
}
else if((ch>'\37')&&(ch<'\173'))
{
putchar(ch);
name[in]=ch;
in++;
}
}
puts("\007");
name[15]='\000';
strcpy(player[i],name);
}
if(numplayers<3) /* Let atari player if less than 4 humans */
{
if(numplayers==0) add_atari(); /* Atari plays if only one human */
else
{
printf("Do you want Atari ST to play? [Y/N] ");
yn=yes_no();
if((yn=='y') || (yn=='Y')) add_atari();
}
}
maxturns=0;
while(maxturns<10 || maxturns>25) /* Set maximun number of turns */
{
vs_curaddress(handle,16,1);
v_eeos(handle);
puts("Press space bar to terminate input.");
printf("How many turns would you like to play? [10-25] ");
scanf("%2d",&maxturns);
putchar('\n');
}
vis_ships=0;
printf("Show enemy ships? [Y/N] ");
yn=yes_no();
if((yn=='y') || (yn=='Y')) vis_ships=1;
limit_pro=0;
printf("Limit neutral planet ship production? [Y/N] ");
yn=yes_no();
if((yn=='y') || (yn=='Y')) limit_pro=1;
vs_curaddress(handle,16,1);
v_eeos(handle);
for(i=0; i<=numplayers; i++)
printf("Player #%d is %s.\n",i+1,player[i]);
printf("The number of turns = %d.\n",maxturns);
printf("See enemy ships = ");
if(vis_ships==1) puts("YES ");
else puts("NO ");
printf("Limit neutral planet ship production = ");
if(limit_pro==1) puts("YES ");
else puts("NO ");
printf("\nAll entries correct? [Y/N] ");
yn=yes_no();
}
}
/* Change size of printed characters */
char_height(height)
int height;
{
int char_width,char_height,cell_width,cell_height;
vst_height(handle,height,&char_width,&char_height,&cell_width,&cell_height);
}
/* Increase players and let Atari enter name */
add_atari()
{
int i;
static char at_string[]="Atari ST\0";
numplayers++;
atari=numplayers;
strcpy(player[numplayers],at_string);
printf("Enter name of player #%d => ",numplayers+1);
for(i=0;i<=7;i++)
{
printf("%c",at_string[i]);
wait(8000L);
}
putchar('\n');
wait(270000L);
}
/* Wait for Y or N keys to be pressed */
yes_no()
{
int xy[2];
char yn='x';
while((yn!='Y') && (yn!='y') && (yn!='N') && (yn!='n'))
vrq_string(handle,1,0,xy,&yn);
printf("%c\n",yn);
return(yn);
}
/* Draw grid to screen */
draw_grid()
{
int pxyarray[4],x,y,i;
x=0;
y=16;
fill_area();
vsl_color(handle,BLACK);
pxyarray[0]=x;
pxyarray[2]=x+639;
for (i=y; i<y+145; i=i+16) /* draw lines across */
{
pxyarray[1]=i;
pxyarray[3]=i;
v_pline(handle,2,pxyarray);
}
pxyarray[1]=y; /* draw lines down */
pxyarray[3]=y+144;
for (i=x; i<x+640; i=i+32)
{
pxyarray[0]=i;
pxyarray[2]=i;
v_pline(handle,2,pxyarray);
}
draw_line();
}
/* Draw line down right edge of screen */
draw_line()
{
int pxyarray[4];
pxyarray[0]=639;
pxyarray[1]=16;
pxyarray[2]=639;
pxyarray[3]=160;
v_pline(handle,2,pxyarray);
}
/* Draw and fill area with color red */
fill_area()
{
vsf_style(handle,3);
draw_l_box(3,RED,0,16,639,160);
}
/* Make square transparent or solid */
shade_area(x,y,mode)
int x,y,mode;
{
v_hide_c(handle);
vsf_style(handle,1);
vswr_mode(handle,mode);
draw_l_box(2,BLACK,x*32+1,y*16+17,x*32+31,y*16+31);
vswr_mode(handle,1);
v_show_c(handle);
}
/* Draw button in area, size, and color passed */
draw_l_box(index,color,x,y,x2,y2)
int index,color,x,y,x2,y2;
{
int pxy[4];
vsf_interior(handle,index);
vsf_color(handle,color);
pxy[0]=x;
pxy[1]=y;
pxy[2]=x2;
pxy[3]=y2;
v_bar(handle,pxy);
}
/* Set up initial board with planets and player positions */
load_grid()
{
int i,row,column,player;
player=1;
for(i=0; i<=numplayers; i++)
{
selec_rc(&row,&column);
contrl_grid[row][column]=player+16;
area_kn[row][column]=player;
numships[row][column]=60; /* Add ships if player at edge */
if(column<9) numships[row][column]+=36-(column*4);
if(column>10) numships[row][column]+=4*column-40;
if(row<4) numships[row][column]+=16-(row*4);
if(row>4) numships[row][column]+=4*row-16;
industry[row][column]=15;
player*=2;
if(atari==i)
{
atari_xy[0]=column;
atari_xy[1]=row;
a_grid[row][column]=1;
}
}
planets=(Random() & 15)+30; /* Number of neutral planets 30-45 */
for(i=0; i<=planets; i++)
{
selec_rc(&row,&column);
contrl_grid[row][column]=16;
industry[row][column]=(Random() & 3)+3;
numships[row][column]=industry[row][column];
}
}
/* Choose row and column from grid */
selec_rc(row,column)
int *row,*column;
{
int num1,num2;
do /* Choose random number within grid */
{
num1=9;
while (num1>8) num1=Random() & 15;
num2=20;
while(num2>19) num2=Random() & 31;
}
while(contrl_grid[num1][num2]>0); /* If occupied, choose another */
*row=num1;
*column=num2;
}
/* Draw box for button */
draw_but(x,y,x2,y2)
int x,y,x2,y2;
{
int xyarray[4];
xyarray[0]=x;
xyarray[1]=y;
xyarray[2]=x2;
xyarray[3]=y2;
v_rbox(handle,xyarray);
}
/* Show player area known and controlled */
display_grid(player)
int player;
{
int row,column,pxy[4],x,y,color;
bit_player=num_player(player);
for(row=0; row<=8; row++) /* player control checked by bits */
for(column=0; column<=19; column++)
if((area_kn[row][column]&bit_player)==bit_player)
{
vsf_interior(handle,1);
vsf_color(handle,WHITE);
pxy[0]=column*32+1;
pxy[1]=row*16+17;
pxy[2]=column*32+31;
pxy[3]=row*16+30;
v_bar(handle,pxy);
x=column*32+15;
y=row*16+23;
if((contrl_grid[row][column]&bit_player)==bit_player)
{ /* Show planets and ships */
vst_color(handle,GREEN);
if(numships[row][column] != 0)
v_gtext(handle,x-3,y+3,"\177");
if((contrl_grid[row][column] & 16)==16)
draw_planet(x,y,GREEN);
}
else if((contrl_grid[row][column] & 31)!=0)
{ /* If enemy, show in red - neutral planet yellow */
vst_color(handle,RED);
if((numships[row][column]>0)&&(vis_ships>0))
v_gtext(handle,x-3,y+3,"\177");
if((contrl_grid[row][column]&16)==16)
{
color=1;
if((contrl_grid[row][column] & 15)!=0)
color=RED;
draw_planet(x,y,color);
}
}
}
vst_color(handle,GREEN);
draw_line();
}
/* Find bit that controls each player */
num_player(player)
int player;
{
int i=0,num=1;
while(i!=player)
{
num*=2;
i++;
}
return(num);
}
/* Draw planet in color passed to procedure */
draw_planet(x,y,color)
int x,y,color;
{
vsf_color(handle,color);
vsf_interior(handle,2);
vsf_style(handle,14);
v_circle(handle,x,y,8);
v_contourfill(handle,x,y,color);
}
/* Accept player input from mouse */
find_orders()
{
int x,y,ox,oy,i,stat,but,numsh,fleet,empty,end=0;
int lt_rt,up_dn,moves,equal_moves,total_moves;
empty=find_start();
but=0;
while(but!=2)
{
v_rvon(handle);
vs_curaddress(handle,22,24);
puts(" ARMADA = ? ");
vs_curaddress(handle,22,45);
puts(" DESTINATION ");
vs_curaddress(handle,22,64);
puts(" ETA = ? ");
numsh=0;
while(numsh==0)
{
vs_curaddress(handle,24,22);
v_rvoff(handle);
puts("- Push Right Mouse Button To End Turn -");
graf_mouse(7,0); /* Change mouse to crosshairs */
v_show_c(handle,0);
but=0;
while(but==0)
{
v_rvoff(handle);
flash_text(10,"ORIGIN");
v_rvon(handle);
flash_text(10,"ORIGIN");
vq_mouse(handle,&stat,&x,&y);
if(y>16 && y<160) but=stat;
if(stat==2)
{
but=2;
vs_curaddress(handle,24,16);
puts("\007 Continue - Left Button / End Turn - Right Button ");
while(but!=0) vq_mouse(handle,&but,&x,&y);
while(but==0) vq_mouse(handle,&but,&x,&y);
erase_line();
wait(1000L);
if(but==1) but=0;
if(but==2) end=2;
}
}
if(end==2) break;
erase_line();
x/=32;y-=16;y/=16;ox=x;oy=y;
if((contrl_grid[y][x] & bit_player)!=bit_player)
{
vs_curaddress(handle,24,21);
puts("\007 That Sector Is Not Controlled By You!!");
wait(150000);
erase_line();
}
else
{
shade_area(x,y,2);
if(industry[y][x]>0)
{
vs_curaddress(handle,24,22);
printf("Planet Manufactures %d Ships Per Turn.",industry[y][x]);
}
if(numships[y][x]>0)
{
numsh=numships[y][x];
vs_curaddress(handle,22,34);
v_rvon(handle);
printf(" %d",numsh);
}
else
{
v_rvoff(handle);
vs_curaddress(handle,24,22);
puts("\007 No Ships Available In This Sector!! ");
wait(150000);
erase_line();
shade_area(x,y,3);
if(x==19) draw_line();
}
}
}
if(end==2) break;
while(but!=0) vq_mouse(handle,&but,&x,&y);
while(but==0)
{
v_rvoff(handle);
flash_text(45,"DESTINATION");
v_rvon(handle);
flash_text(45,"DESTINATION");
vq_mouse(handle,&stat,&x,&y);
if(y>16 && y<160) but=stat;
}
erase_line();
x/=32;y-=16;y/=16;
if(x==ox && y==oy)
{
shade_area(x,y,3);
if(x==19) draw_line();
}
else
{
lt_rt=0;
up_dn=0;
shade_area(x,y,2);
lt_rt=(x<ox) ? ox-x : x-ox;
up_dn=(y<oy) ? oy-y : y-oy;
moves=(up_dn<lt_rt) ? lt_rt-up_dn : up_dn-lt_rt;
equal_moves=(up_dn<lt_rt) ? lt_rt-moves : up_dn-moves;
total_moves=equal_moves+moves;
if(total_moves>1) total_moves/=2;
v_rvon(handle);
vs_curaddress(handle,22,70);
printf(" %d",total_moves);
fleet=send_ships(numsh);
vs_curaddress(handle,23,1);
v_hide_c(handle);
v_eeos(handle);
if(fleet>0)
{
numships[oy][ox]-=fleet;
orders[empty].eta=total_moves;
orders[empty].owner=bit_player;
orders[empty].shipsent=fleet;
orders[empty].xs=x;
orders[empty].ys=y;
orders[empty].xf=ox;
orders[empty].yf=oy;
empty++;
}
}
shade_area(x,y,3);
shade_area(ox,oy,3);
if((x==19)||(ox==19)) draw_line();
}
}
/* Erase text line from bottom of screen */
erase_line()
{
vs_curaddress(handle,24,10);
v_rvoff(handle);
printf(" ");
}
/* Display text in inverse or standard */
flash_text(x,text)
int x;
char text[12];
{
vs_curaddress(handle,22,x);
printf(" %s ",text);
wait(6000L);
}
/* Find number of ships to send */
send_ships(total)
int total;
{
int num=0,send=0,button=0,stat,x,y;
graf_mouse(3,0);
while(send==0)
{
v_hide_c(handle);
draw_l_box(0,RED,204,180,356,194);
v_rvoff(handle);
vs_curaddress(handle,24,28);
printf("Send %3d Ship(s)",num);
draw_l_box(0,RED,384,180,402,194);
v_gtext(handle,390,190,"\001");
draw_l_box(0,RED,408,180,426,194);
v_gtext(handle,414,190,"\002");
v_show_c(handle,0);
while(button!=1)
{
vq_mouse(handle,&stat,&x,&y);
if(y>180 && y<194)
button=stat;
}
v_hide_c(handle);
if(x>204 && x<356)
{
send=1;
draw_l_box(1,1,205,181,355,193);
v_rvon(handle);
vs_curaddress(handle,24,28);
printf("Send %3d Ship(s)",num);
v_rvoff(handle);
v_show_c(handle,0);
while(button==1)
vq_mouse(handle,&button,&x,&y);
}
if(x>384 && x<402)
{
draw_l_box(1,1,385,181,401,193);
v_gtext(handle,390,190,"\001");
v_show_c(handle,0);
while(button==1)
{
num+=1;
if(num>total) num=total;
vs_curaddress(handle,24,33);
printf("%3d",num);
wait(5000L);
vq_mouse(handle,&button,&x,&y);
}
}
if(x>408 && x<426)
{
draw_l_box(1,1,409,181,425,193);
v_gtext(handle,414,190,"\002");
v_show_c(handle,0);
while(button==1)
{
num-=1;
if(num<0) num=0;
vs_curaddress(handle,24,33);
printf("%3d",num);
wait(5000L);
vq_mouse(handle,&button,&x,&y);
}
}
v_show_c(handle,0);
button=0;
}
return(num);
}
/* Find empty spot in structured array to store orders */
find_start()
{
int i=0;
while(orders[i].eta != 0) i++;
return(i);
}
/* Read orders and execute */
move_players()
{
int i=0,x,y,results,planet,num;
short temp;
char message[60];
while(orders[i].eta != 0)
{
orders[i].eta--;
if(orders[i].eta==0)
{
num=find_admiral(orders[i].owner);
strcpy(message,a_orders);
strcat(message,player[num]);
vs_curaddress(handle,1,1);
puts("\007");
vst_color(handle,WHITE);
v_gtext(handle,40,10,"000000000000000000000000000000000000000000");
v_gtext(handle,320,10,"00000000000000000000000000000000000");
vst_color(handle,RED);
v_gtext(handle,136,10,message);
x=orders[i].xs;
y=orders[i].ys;
temp=(area_kn[y][x]&15);
temp=(temp | orders[i].owner);
area_kn[y][x]=temp;
shade_area(x,y,2);
if(numships[y][x] != 0) /* If other ships occupy grid - fight */
{
results=battle(x,y,i);
vs_curaddress(handle,24,23);
switch(results)
{
case 0:
printf("** Attacker Was Defeated!! **");
break;
case 1:
printf(" Attacker Was Suscessful!!");
numships[y][x]=orders[i].shipsent;
planet=(contrl_grid[y][x]&16);
contrl_grid[y][x]=orders[i].owner+planet;
break;
case 2:
printf("Area reinforced with %d ship(s).",orders[i].shipsent);
numships[y][x]+=orders[i].shipsent;
break;
case 3:
printf(" ~~ Attacker Retreated!! ~~");
orders[i].eta=(Random() & 3)+1;
orders[i].xs=orders[i].xf;
orders[i].ys=orders[i].yf;
orders[i].xf=Random()&15;
orders[i].yf=Random()&7;
break;
}
}
else
{
vs_curaddress(handle,24,27);
printf(" ^^^ %d Ship(s) Arriving. ^^^",orders[i].shipsent);
planet=(contrl_grid[y][x]&16);
contrl_grid[y][x]=orders[i].owner+planet;
numships[y][x]=orders[i].shipsent;
}
wait(250000);
shade_area(x,y,3);
if(x==19) draw_line();
erase_line();
vs_curaddress(handle,22,1);
v_hide_c(handle);
v_eeos(handle);
v_show_c(handle);
}
i++;
}
}
/* Execute battle and return results */
battle(x,y,ord)
int x,y,ord;
{
int num,dshots,ashots,achance,dchance,attships,player,maxshots;
int quit=1,i,mx,my,hit,won_lost,button,stop=0,shields=1,dshields=0;
if((contrl_grid[y][x]&orders[ord].owner)==orders[ord].owner)
won_lost=2;
else
{
draw_l_box(1,1,2,166,637,176);
achance=(Random()&31)+69;
dchance=(Random()&31)+69;
v_rvon(handle);
vs_curaddress(handle,22,2);
attships=orders[ord].shipsent;
printf("Attacker has %3d ships -%3d%% accuracy --",attships,achance);
vs_curaddress(handle,22,43);
printf("Defender has %3d ships -%3d%% accuracy",numships[y][x],dchance);
vs_curaddress(handle,24,12);
printf(" Press left button to attack - right button to retreat! ");
player=find_admiral(orders[ord].owner);
if(player==atari)
{
wait(30000L);
if((numships[y][x]/attships)>2) quit=0;
}
else
{
while(button!=0) vq_mouse(handle,&button,&mx,&my);
while(button==0) vq_mouse(handle,&button,&mx,&my);
if(button==2) quit=0;
while(button!=0) vq_mouse(handle,&button,&mx,&my);
}
erase_line();
while(orders[ord].shipsent>0 && numships[y][x]>0 && quit>0)
{
v_rvon(handle);
dshots=numships[y][x];
if((contrl_grid[y][x]&15)!=0)
{
dshots+=numships[y][x]/2;
if((contrl_grid[y][x]&16)==16)
{
dshots+=numships[y][x]/2;
shields=2;
dshields=1;
}
}
ashots=orders[ord].shipsent;
maxshots=(ashots>dshots) ? ashots : dshots;
for(i=1; i<=maxshots; i++)
{
if(ashots>0)
{
ashots--;
fire(170);
hit=odds(achance);
if(hit==1)
{
if(dshields==0)
{
numships[y][x]--;
vs_curaddress(handle,22,55);
printf("%4d",numships[y][x]);
dshields=shields;
}
hit_sound();
dshields--;
}
sound_off();
if(numships[y][x]==0)
{
stop=1;
break;
}
}
if(dshots>0)
{
dshots--;
fire(480);
hit=odds(dchance);
if(hit==1)
{
orders[ord].shipsent--;
vs_curaddress(handle,22,14);
printf("%4d",orders[ord].shipsent);
hit_sound();
}
sound_off();
if(orders[ord].shipsent==0)
{
stop=1;
break;
}
}
vq_mouse(handle,&button,&mx,&my);
if(button!=0)
{
vs_curaddress(handle,24,12);
v_rvoff(handle);
printf("Left button to continue attack - Right button to retreat");
while(button!=0) vq_mouse(handle,&button,&mx,&my);
while(button==0) vq_mouse(handle,&button,&mx,&my);
erase_line();
v_rvon(handle);
if(button==2) quit=0;
}
if(quit==0) break;
if(stop==1) break;
}
}
won_lost=(orders[ord].shipsent>numships[y][x])? 1 : 0;
}
if(quit==0)
{
won_lost=3;
if(orders[ord].shipsent>10)
orders[ord].shipsent-=orders[ord].shipsent/10;
}
v_rvoff(handle);
return(won_lost);
}
/* Move orders in array to fill empty spaces */
pack_orders()
{
int i,start,empty;
empty=find_start();
start=empty;
for(i=start; i<=300; i++)
if(orders[i].eta != 0)
{
orders[empty].eta=orders[i].eta;
orders[i].eta=0;
orders[empty].owner=orders[i].owner;
orders[empty].shipsent=orders[i].shipsent;
orders[empty].xs=orders[i].xs;
orders[empty].ys=orders[i].ys;
orders[empty].xf=orders[i].xf;
orders[empty].yf=orders[i].yf;
empty++;
}
}
/* Draw expanding red box and create sound */
fire(side)
int side;
{
char note_hi,note_lo;
int i,tone1=202,tone2=304;
volume=10;
Giaccess(volume,cha_vol+wr_command);
Giaccess(volume,chb_vol+wr_command);
for(i=4; i<=152; i+=4)
{
draw_l_box(1,RED,side-i,182,side+i,196);
tone1-=4;
note_hi=(tone1&hi_mask)>>8;
note_lo=(tone1&lo_mask);
Giaccess(note_lo,cha_lo+wr_command);
Giaccess(note_hi,cha_hi+wr_command);
tone2-=4;
note_hi=(tone2&hi_mask)>>8;
note_lo=(tone2&lo_mask);
Giaccess(note_lo,chb_lo+wr_command);
Giaccess(note_hi,chb_hi+wr_command);
wait(100L);
}
draw_l_box(0,0,side-i,182,side+i,196);
}
/* Calulate chance of miss or hit */
odds(chance)
int chance;
{
int shot,results;
do
shot=Random() & 127;
while(shot>100);
results=(shot>chance)? 0:1;
return(results);
}
/* Build ships for each planet */
add_industry()
{
int r,c;
for(r=0; r<=8; r++)
for(c=0; c<=19; c++)
{
numships[r][c]+=industry[r][c];
if((limit_pro==1)&&((contrl_grid[r][c]&15)==0)&&(numships[r][c]>30))
numships[r][c]=30;
}
}
/* Find player number */
find_admiral(i)
int i;
{
int results;
results=i;
if(i<4) results-=1;
else results/=2;
if(results==4) results-=1;
return(results);
}
/* BANG */
hit_sound()
{
char note_hi,note_lo;
int tone1,tone2;
volume=15;
Giaccess(volume,cha_vol+wr_command);
Giaccess(volume,chb_vol+wr_command);
for(tone1=1280; tone1<=2580; tone1+=10)
{
tone2=tone1+640;
note_hi=(tone1&hi_mask)>>8;
note_lo=(tone1&lo_mask);
Giaccess(note_lo,cha_lo+wr_command);
Giaccess(note_hi,cha_hi+wr_command);
note_hi=(tone2&hi_mask)>>8;
note_lo=(tone2&lo_mask);
Giaccess(note_lo,chb_lo+wr_command);
Giaccess(note_hi,chb_hi+wr_command);
wait(120L);
}
}
/* Show status of all players each 5 turns */
show_status()
{
int i,but,x,y,tot_ships,tot_planets,admiral=1;
v_hide_c(handle);
color_reg(1,0,0,0);
color_reg(0,1000,1000,1000);
v_clrwk(handle);
v_rvon(handle);
vs_curaddress(handle,1,32);
printf(" Turn # %d ",turn_num);
if(turn_num==maxturns) puts(" GAME OVER! ");
for(i=0; i<=numplayers; i++)
{
v_rvon(handle);
vs_curaddress(handle,i*5+3,15);
printf("~~~~~~~ Status of Fleet Admiral %s ~~~~~~~",player[i]);
v_rvoff(handle);
bit_player=admiral;
admiral*=2;
count(&tot_ships,&tot_planets);
vs_curaddress(handle,i*5+4,30);
printf("Total Ships = %d",tot_ships);
vs_curaddress(handle,i*5+5,30);
printf("Total Planets = %d",tot_planets);
vs_curaddress(handle,i*5+6,30);
printf("Known Area = %d",explored);
vs_curaddress(handle,i*5+7,30);
printf("Score = %d",score);
}
}
/* Kill sound */
sound_off()
{
Giaccess(0,cha_vol+wr_command);
Giaccess(0,chb_vol+wr_command);
}
/* Show final grid for all players */
final_show()
{
int i,tot_ships,tot_planets,but,x,y;
v_hide_c(handle);
vst_color(handle,GREEN);
for(i=0; i<=numplayers; i++)
{
v_clrwk(handle);
draw_grid();
display_grid(i);
vs_curaddress(handle,1,9);
printf(" Final Status Report For Fleet Admiral %s. ",player[i]);
count(&tot_ships,&tot_planets);
vs_curaddress(handle,2,2);
printf("Total Ships = %3d ~~ Total Planets = %2d ~~ ",tot_ships,tot_planets);
printf("Known Area = %3d ~~ Score = %5d",explored,score);
vs_curaddress(handle,24,26);
v_rvon(handle);
puts(" Press Button to Continue ");
v_rvoff(handle);
but=0;
while(but==0) vq_mouse(handle,&but,&x,&y);
}
v_show_c(handle,0);
}
/* Atari's turn to play */
a_play(player) /* Check for Atari control */
int player;
{
int r,c,p;
bit_player=num_player(player);
p=bit_player;
for(r=0;r<=8;r++)
for(c=0;c<=19;c++)
if(((contrl_grid[r][c]&p)==p)&&(numships[r][c]>0)) search(r,c);
}
/* Search for unexplored territory and planets to attack */
search(r,c) /* Four search patterns for orders */
int r,c;
{
int x,y,pattern,flag=0;
pattern=Random()&3;
switch(pattern) /* Primary orders search and attack */
{
case 0:
for(y=r-3;y<=r+3;y++)
for(x=c-3;x<=c+3;x++)
if((x>-1)&&(x<20)&&(y>-1)&&(y<9)&&(numships[r][c]>0))
flag=primary_orders(r,c,y,x);
break;
case 1:
for(x=c-3;x<=c+3;x++)
for(y=r-3;y<=r+3;y++)
if((x>-1)&&(x<20)&&(y>-1)&&(y<9)&&(numships[r][c]>0))
flag=primary_orders(r,c,y,x);
break;
case 2:
for(y=r+3;y>=r-3;y--)
for(x=c+3;x>=c-3;x--)
if((x>-1)&&(x<20)&&(y>-1)&&(y<9)&&(numships[r][c]>0))
flag=primary_orders(r,c,y,x);
break;
case 3:
for(x=c+3;x>=c-3;x--)
for(y=r+3;y>=r-3;y--)
if((x>-1)&&(x<20)&&(y>-1)&&(y<9)&&(numships[r][c]>0))
flag=primary_orders(r,c,y,x);
break;
}
if(flag==0)
{
switch(pattern) /* Secondary orders re-inforce planet */
{
case 0:
for(y=r-3;y<=r+3;y++)
for(x=c-3;x<=c+3;x++)
if((x>-1)&&(x<20)&&(y>-1)&&(y<9)&&(numships[r][c]>0))
flag=secondary_orders(r,c,y,x);
break;
case 1:
for(x=c-3;x<=c+3;x++)
for(y=r-3;y<=r+3;y++)
if((x>-1)&&(x<20)&&(y>-1)&&(y<9)&&(numships[r][c]>0))
flag=secondary_orders(r,c,y,x);
break;
case 2:
for(y=r+3;y>=r-3;y--)
for(x=c+3;x>=c-3;x--)
if((x>-1)&&(x<20)&&(y>-1)&&(y<9)&&(numships[r][c]>0))
flag=secondary_orders(r,c,y,x);
break;
case 3:
for(x=c+3;x>=c-3;x--)
for(y=r+3;y>=r-3;y--)
if((x>-1)&&(x<20)&&(y>-1)&&(y<9)&&(numships[r][c]>0))
flag=secondary_orders(r,c,y,x);
break;
}
}
if((flag==0)&&((contrl_grid[r][c]&16)!=16)) go_home(r,c);
}
/* Explore and attack */
primary_orders(r,c,y,x)
int r,c,y,x;
{
int flag=0;
if((contrl_grid[r][c]&16)==16)
{
if(numships[r][c]>15)
{
if(a_grid[y][x]==0)
{
if(turn_num==0) store_a_orders(r,c,y,x,5);
else store_a_orders(r,c,y,x,1);
a_grid[y][x]=1;
}
if((area_kn[y][x]&bit_player)==bit_player)
{
if((contrl_grid[y][x]&31)==16)
s_a_fleet(r,c,y,x);
if(((contrl_grid[y][x]&31)>16)&&(numships[y][x]<10))
s_a_fleet(r,c,y,x);
}
}
flag=1;
}
else if(a_grid[y][x]==0)
{
store_a_orders(r,c,y,x,1);
a_grid[y][x]=1;
flag=1;
}
return(flag);
}
/* Re-inforce planets */
secondary_orders(r,c,y,x)
int r,c,y,x;
{
int ct,fleet,flag=0;
ct=bit_player+16;
if((contrl_grid[y][x]&ct)==ct)
{
if(((contrl_grid[r][c]&16)==16)&&(numships[r][c]>20))
{
fleet=numships[r][c]-15;
store_a_orders(r,c,y,x,fleet);
}
else store_a_orders(r,c,y,x,numships[r][c]);
flag=1;
}
return(flag);
}
/* Send a fleet to conquer */
s_a_fleet(r,c,y,x)
int r,c,y,x;
{
int fleet;
if(numships[r][c]>25)
{
fleet=numships[r][c]-12;
if(fleet>(6*turn_num+6))
{
fleet=6*turn_num+6;
store_a_orders(r,c,y,x,fleet);
}
else if((limit_pro==1)&&(turn_num>4)&&(fleet>35))
{
fleet=35;
store_a_orders(r,c,y,x,fleet);
}
}
}
/* Unable to explore or conquer - go to home planet */
go_home(r,c)
int r,c;
{
int x,y;
x=atari_xy[0];
y=atari_xy[1];
store_a_orders(r,c,y,x,numships[r][c]);
}
/* Place Atari orders in array */
store_a_orders(r,c,y,x,fleet)
int r,c,y,x,fleet;
{
int empty;
empty=find_start();
numships[r][c]-=fleet;
orders[empty].eta=1;
orders[empty].owner=bit_player;
orders[empty].shipsent=fleet;
orders[empty].xs=x;
orders[empty].ys=y;
orders[empty].xf=c;
orders[empty].yf=r;
}
/* Save for a later date */
save_game()
{
int button,wr_handle,i,j,ct;
wr_handle= -1;
for(i=0;i<=8;i++)
for(j=0;j<=19;j++)
{
buffer[j+(i*20)]=contrl_grid[i][j];
buffer[j+180+(i*20)]=area_kn[i][j];
buffer[j+360+(i*20)]=numships[i][j];
buffer[j+540+(i*20)]=industry[i][j];
buffer[j+720+(i*20)]=a_grid[i][j];
}
for(i=0;i<=3;i++)
for(j=0;j<=20;j++)
buffer[j+900+(i*21)]=player[i][j];
buffer[1000]=numplayers;
buffer[1001]=turn_num;
buffer[1002]=maxturns;
buffer[1003]=vis_ships;
buffer[1004]=limit_pro;
buffer[1005]=atari;
buffer[1006]=atari_xy[0];
buffer[1007]=atari_xy[1];
ct=find_start();
buffer[1008]=ct;
for(i=0;i<=ct;i++)
{
buffer[1010+(i*7)]=orders[i].eta;
buffer[1011+(i*7)]=orders[i].owner;
buffer[1012+(i*7)]=orders[i].shipsent;
buffer[1013+(i*7)]=orders[i].xs;
buffer[1014+(i*7)]=orders[i].ys;
buffer[1015+(i*7)]=orders[i].xf;
buffer[1016+(i*7)]=orders[i].yf;
}
v_show_c(handle,0);
drive=Dgetdrv();
path[0]=(drive+'A');
fsel_input(path,io_file,&button);
if(button!=0)
{
wr_handle=Fcreate(io_file,0);
if(wr_handle> -1)
Fwrite(wr_handle,f_length,buffer);
Fclose(wr_handle);
}
v_hide_c(handle);
return(wr_handle);
}
/* Restore old game */
load_game()
{
int button,rd_handle,i,j,ct;
char rn;
rd_handle= -1;
rn=question();
if(rn=='R' || rn=='r')
{
v_show_c(handle,0);
drive=Dgetdrv();
path[0]=(drive+'A');
fsel_input(path,io_file,&button);
if(button!=0)
{
rd_handle=Fopen(io_file,0);
if(rd_handle>-1)
Fread(rd_handle,f_length,buffer);
Fclose(rd_handle);
for(i=0;i<=8;i++)
for(j=0;j<=19;j++)
{
contrl_grid[i][j]=buffer[j+(i*20)];
area_kn[i][j]=buffer[j+180+(i*20)];
numships[i][j]=buffer[j+360+(i*20)];
industry[i][j]=buffer[j+540+(i*20)];
a_grid[i][j]=buffer[j+720+(i*20)];
}
for(i=0;i<=3;i++)
for(j=0;j<=20;j++)
player[i][j]=buffer[j+900+(i*21)];
numplayers=buffer[1000];
turn_num=buffer[1001];
maxturns=buffer[1002];
vis_ships=buffer[1003];
limit_pro=buffer[1004];
atari=buffer[1005];
atari_xy[0]=buffer[1006];
atari_xy[1]=buffer[1007];
ct=buffer[1008];
for(i=0;i<=ct;i++)
{
orders[i].eta=buffer[1010+(i*7)];
orders[i].owner=buffer[1011+(i*7)];
orders[i].shipsent=buffer[1012+(i*7)];
orders[i].xs=buffer[1013+(i*7)];
orders[i].ys=buffer[1014+(i*7)];
orders[i].xf=buffer[1015+(i*7)];
orders[i].yf=buffer[1016+(i*7)];
}
}
v_hide_c(handle);
}
return(rd_handle);
}
/* New game or old */
question()
{
char rn;
int xy[2];
vs_curaddress(handle,14,27);
v_rvon(handle);
printf("N");
v_rvoff(handle);
printf("ew game - ");
v_rvon(handle);
printf("R");
v_rvoff(handle);
printf("estore old game");
while((rn!='r')&&(rn!='R')&&(rn!='n')&&(rn!='N'))
vrq_string(handle,1,0,xy,&rn);
return(rn);
}