home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume19
/
xtmines
/
part01
/
init.c
next >
Wrap
C/C++ Source or Header
|
1993-04-28
|
17KB
|
495 lines
/* xtmines: game where you try to cross a minefield */
/* windows.c: routines to initialize windows, fonts, GCs, etc */
/* Written by Timothy Tsai April 13, 1992 */
#include "xtmines.h"
/* open_display: open the display; */
/* set up default values */
/* (eg. root, white, black, etc) */
/* set random seed */
void open_display()
{
if ((disp = XOpenDisplay(NULL)) == NULL) {
fprintf(stderr, "Can't Open Display\n");
exit(1);
}
root = DefaultRootWindow(disp);
screen = DefaultScreen(disp);
depth = DefaultDepth(disp,screen);
visual = DefaultVisual(disp,screen);
white = WhitePixel(disp,screen);
black = BlackPixel(disp,screen);
srandom(time(0));
}
/* load_fonts: load 3 fonts: fonts (status line and showfig) */
/* fontm (main -- for most text) */
/* fontt (time and hiscores list) */
void load_fonts()
{
fonts = XLoadFont(disp,FONTS);
fontsstruct = XQueryFont(disp,fonts);
/* fontsw, fontsh, fontsa are used by PrintStr() for status line */
fontsw = fontsstruct->max_bounds.rbearing -
fontsstruct->min_bounds.lbearing;
fontsh = fontsstruct->ascent + fontsstruct->descent;
fontsa = fontsstruct->ascent;
/* fonstshoww, fontshowh, fontshowa are used by draw() for showfig */
fontshoww = (fontsstruct->per_char + '0')->rbearing -
(fontsstruct->per_char + '0')->lbearing;
fontshowh = (fontsstruct->per_char + '0')->ascent +
(fontsstruct->per_char + '0')->descent;
fontshowa = (fontsstruct->per_char + '0')->ascent;
fontm = XLoadFont(disp,FONTM);
fontmstruct = XQueryFont(disp,fontm);
fontmw = fontmstruct->max_bounds.rbearing -
fontmstruct->min_bounds.lbearing;
fontmh = fontmstruct->ascent + fontmstruct->descent;
fontma = fontmstruct->ascent;
fontt = XLoadFont(disp,FONTT);
fonttstruct = XQueryFont(disp,fontt);
fonttw = fonttstruct->max_bounds.rbearing -
fonttstruct->min_bounds.lbearing;
fontth = fonttstruct->ascent + fonttstruct->descent;
fontta = fonttstruct->ascent;
}
/* create_map_frame: actually create each window and map to screen */
/* this is where each window's position and size */
/* are specified; also, create all bitmaps and */
/* initialize bitmaps dimension arrays */
void create_map_frame()
{
int ww, /* window width of small button windows */
wh1, /* window height of status line right under field */
wh2, /* 2nd row of buttons */
wh3, /* 3rd row of buttons */
wh4; /* last row of buttons */
/*---First, create and map windows----------------------------*/
/* first wind button widths and heights */
/* NUM1WINDS = num of buttons in one row */
ww = (w-(NUM1WINDS+1)*bw)/(NUM1WINDS);
wh1 = wh2 = wh3 = (h-fh-6*bw)/4; wh4 = h-fh-6*bw-wh1-wh2-wh3;
/* create frame and field */
frame = XCreateSimpleWindow(disp,root,x,y,w,h,bw,black,white);
field = XCreateSimpleWindow(disp,frame,
0,0,w-2*bw,fh,bw,
black,white);
/* create status line */
wind[status] = XCreateSimpleWindow(disp,frame,
0,fh+bw,w-2*bw,wh1,bw,
black,white);
/* create 2nd button row */
wind[bombs_left] = XCreateSimpleWindow(disp,frame,
0,fh+wh1+2*bw,ww,
wh2,bw,black,white);
wind[bonus_wind] = XCreateSimpleWindow(disp,frame,
bonus_wind*(ww+bw),
fh+wh1+2*bw,ww,
wh2,bw,black,white);
wind[time_left] = XCreateSimpleWindow(disp,frame,
time_left*(ww+bw),
fh+wh1+2*bw,ww,
wh2,bw,black,white);
wind[score] = XCreateSimpleWindow(disp,frame,
score*(ww+bw),
fh+wh1+2*bw,ww,
wh2,bw,black,white);
wind[grenades_left] = XCreateSimpleWindow(disp,frame,
grenades_left*(ww+bw),
fh+wh1+2*bw,ww,
wh2,bw,black,white);
wind[rank] = XCreateSimpleWindow(disp,frame,
rank*(ww+bw),
fh+wh1+2*bw,w-2*bw-(rank)*(ww+bw),
wh2,bw,black,white);
/* create 3rd button row */
wind[quit_wind] = XCreateSimpleWindow(disp,frame,
rank*(ww+bw),
fh+3*bw+wh1+wh2,w-2*bw-(rank)*(ww+bw),
wh3,bw,black,white);
wind[show_wind] = XCreateSimpleWindow(disp,frame,
grenades_left*(ww+bw),
fh+3*bw+wh1+wh2,ww,
wh3,bw,black,white);
wind[tgrenade_wind] = XCreateSimpleWindow(disp,frame,
score*(ww+bw),
fh+3*bw+wh1+wh2,ww,
wh3,bw,black,white);
wind[giveup_wind] = XCreateSimpleWindow(disp,frame,
time_left*(ww+bw),
fh+3*bw+wh1+wh2,ww,
wh3,bw,black,white);
wind[automark_wind] = XCreateSimpleWindow(disp,frame,
bonus_wind*(ww+bw),
fh+3*bw+wh1+wh2,ww,
wh3,bw,black,white);
wind[lives_left] = XCreateSimpleWindow(disp,frame,
0,fh+3*bw+wh1+wh2,ww,
wh3,bw,black,white);
/* create last button row */
/* These are for future expansion
wind[] = XCreateSimpleWindow(disp,frame,
rank*(ww+bw),
fh+4*bw+wh1+wh2+wh3,
w-2*bw-(rank)*(ww+bw),
wh4,bw,black,white);
wind[] = XCreateSimpleWindow(disp,frame,
grenades_left*(ww+bw),
fh+4*bw+wh1+wh2+wh3,ww,
wh4,bw,black,white);
*/
wind[pause_wind] = XCreateSimpleWindow(disp,frame,
score*(ww+bw),
fh+4*bw+wh1+wh2+wh3,ww,
wh4,bw,black,white);
wind[sanitycheck_wind] = XCreateSimpleWindow(disp,frame,
time_left*(ww+bw),
fh+4*bw+wh1+wh2+wh3,ww,
wh4,bw,black,white);
wind[eautomark_wind] = XCreateSimpleWindow(disp,frame,
bonus_wind*(ww+bw),
fh+4*bw+wh1+wh2+wh3,ww,
wh4,bw,black,white);
wind[refresh_wind] = XCreateSimpleWindow(disp,frame,
0,fh+4*bw+wh1+wh2+wh3,ww,
wh4,bw,black,white);
/* set window and icon names */
XStoreName(disp,frame,"xtmines");
XSetIconName(disp,frame,"xtmines");
/* Map all windows to screen */
XMapRaised(disp,frame);
XMapRaised(disp,field);
XMapRaised(disp,wind[bombs_left]);
XMapRaised(disp,wind[bonus_wind]);
XMapRaised(disp,wind[time_left]);
XMapRaised(disp,wind[score]);
XMapRaised(disp,wind[grenades_left]);
XMapRaised(disp,wind[rank]);
XMapRaised(disp,wind[quit_wind]);
XMapRaised(disp,wind[show_wind]);
XMapRaised(disp,wind[tgrenade_wind]);
XMapRaised(disp,wind[giveup_wind]);
XMapRaised(disp,wind[automark_wind]);
XMapRaised(disp,wind[lives_left]);
XMapRaised(disp,wind[pause_wind]);
XMapRaised(disp,wind[sanitycheck_wind]);
XMapRaised(disp,wind[eautomark_wind]);
XMapRaised(disp,wind[refresh_wind]);
XMapRaised(disp,wind[status]);
/*---Now initialize all bitmaps and accompanying dimensions---*/
/* load all bitmaps into memory */
bitmap[bm_safe] = XCreateBitmapFromData(disp,field,
safe_bits,safe_width,safe_height);
bitmap[bm_man] = XCreateBitmapFromData(disp,field,
man_bits,man_width,man_height);
bitmap[bm_bomb] = XCreateBitmapFromData(disp,field,
bomb_bits,bomb_width,bomb_height);
bitmap[bm_tombstone] = XCreateBitmapFromData(disp,field,
tstone_bits,tstone_width,tstone_height);
bitmap[bm_goal] = XCreateBitmapFromData(disp,field,
goal_bits,goal_width,goal_height);
bitmap[bm_trail] = XCreateBitmapFromData(disp,field,
trail_bits,trail_width,trail_height);
bitmap[bm_pow] = XCreateBitmapFromData(disp,field,
pow_bits,pow_width,pow_height);
bitmap[bm_bombmark] = XCreateBitmapFromData(disp,field,
bombmark_bits,bombmark_width,
bombmark_height);
bitmap[bm_safewrong] = XCreateBitmapFromData(disp,field,
safewrong_bits,safewrong_width,
safewrong_height);
bitmap[bm_bombmarkwrong]= XCreateBitmapFromData(disp,field,
bombmarkwrong_bits,bombmarkwrong_width,
bombmarkwrong_height);
/* put all bitmap dimensions into width and height arrays */
bmwidth[bm_safe] = safe_width;
bmwidth[bm_man] = man_width;
bmwidth[bm_bomb] = bomb_width;
bmwidth[bm_tombstone] = tstone_width;
bmwidth[bm_goal] = goal_width;
bmwidth[bm_trail] = trail_width;
bmwidth[bm_pow] = pow_width;
bmwidth[bm_bombmark] = bombmark_width;
bmwidth[bm_safewrong] = safewrong_width;
bmwidth[bm_bombmarkwrong] = bombmarkwrong_width;
bmheight[bm_safe] = safe_height;
bmheight[bm_man] = man_height;
bmheight[bm_bomb] = bomb_height;
bmheight[bm_tombstone] = tstone_height;
bmheight[bm_goal] = goal_height;
bmheight[bm_trail] = trail_height;
bmheight[bm_pow] = pow_height;
bmheight[bm_bombmark] = bombmark_height;
bmheight[bm_safewrong] = safewrong_height;
bmheight[bm_bombmarkwrong] = bombmarkwrong_height;
}
/* create_GC_colormap: set up Graphics Contexts and colormaps */
/* right now, there are only 2 colors (black & white) */
void create_GC_colormap()
{
XGCValues gcv; /* to determine attributes to set */
XColor exact; /* used by XAllocNamedColor; */
/* return value is never used */
/* set up gcs -- GC for status line and showfig */
gcv.font = fonts;
gcv.line_width = 1;
gcv.graphics_exposures = FALSE;
gcs = XCreateGC(disp,frame,
GCFont | GCLineWidth | GCGraphicsExposures,
&gcv);
/* set up gcm -- GC for main (most text) */
gcv.font = fontm;
gcv.line_width = 1;
gcv.graphics_exposures = FALSE;
gcm = XCreateGC(disp,frame,
GCFont | GCLineWidth | GCGraphicsExposures,
&gcv);
/* set up gct -- GC for time and hiscores list */
gcv.font = fontt;
gcv.line_width = 1;
gcv.graphics_exposures = FALSE;
gct = XCreateGC(disp,frame,
GCFont | GCLineWidth | GCGraphicsExposures,
&gcv);
/* Set up colormap */
cmap = XDefaultColormap(disp,screen);
XAllocNamedColor(disp,cmap,FONTCOLOR,&color[font_color],&exact);
XAllocNamedColor(disp,cmap,BACKGROUNDCOLOR,&color[background_color],
&exact);
XAllocNamedColor(disp,cmap,FIELDCOLOR,&color[field_color],
&exact);
}
/* set_event_masks: all event masks are set here */
void set_event_masks()
{
int i;
windtype windownum;
/* set exposure mask for all windows */
XSelectInput(disp,frame,ExposureMask);
for (windownum=0;windownum<NUMWINDS;windownum++)
XSelectInput(disp,wind[windownum],ExposureMask);
/* check to see if quit */
XSelectInput(disp,wind[quit_wind],ButtonPressMask|ExposureMask);
/* check to see if toggle show */
XSelectInput(disp,wind[show_wind],ButtonPressMask|ExposureMask);
/* check to see if throw grenades */
XSelectInput(disp,wind[tgrenade_wind],ButtonPressMask|ExposureMask);
/* check to see if give up */
XSelectInput(disp,wind[giveup_wind],ButtonPressMask|ExposureMask);
/* check to see if toggle automark */
XSelectInput(disp,wind[automark_wind],ButtonPressMask|ExposureMask);
/* check to see if toggle pause */
XSelectInput(disp,wind[pause_wind],ButtonPressMask|ExposureMask);
/* check to see if toggle sanity check */
XSelectInput(disp,wind[sanitycheck_wind],ButtonPressMask|ExposureMask);
/* check to see if toggle extended_automark */
XSelectInput(disp,wind[eautomark_wind],ButtonPressMask|ExposureMask);
/* check to see if refresh */
XSelectInput(disp,wind[refresh_wind],ButtonPressMask|ExposureMask);
/* allow mouse button and key presses in field */
XSelectInput(disp,field,KeyPressMask|ButtonPressMask|ExposureMask);
}
/* init_values: called at the beginning of every level */
/* sets num_bombs_left, num_time_left_at_start */
/* num_time_left, used_showfig, */
/* used_sanity, used_eautomark */
int num_bombs_at_start[NUMRANKS];
void init_values()
{
num_bombs_at_start[grunt] = 50;
num_bombs_at_start[corporal] = 100;
num_bombs_at_start[lieutenant] = 150;
num_bombs_at_start[captain] = 200;
num_bombs_at_start[mmajor] = 250;
num_bombs_at_start[general] = 300;
num_bombs_at_start[president] = 350;
num_bombs_at_start[king] = 400;
num_bombs_at_start[emperor] = 450;
num_bombs_at_start[angel] = 500;
num_tombstones = 0;
num_bombs_left = num_bombs_at_start[level];
num_time_left_at_start = SECONDS_PER_LEVEL*(level+1);
num_time_left = num_time_left_at_start;
pause_time = 0;
used_showfig = (show==sh_fig) ? TRUE : FALSE;
used_sanity = (sanity) ? TRUE : FALSE;
used_eautomark = (extended_automark) ? TRUE : FALSE;
num_bonus = current_bonus();
}
/* illegal_bomb_position: input a virtual field position */
/* output a boolean=is bomb allowed here? */
/* illegal is more than two bombs around goal */
/* 4 most top-left squares */
int illegal_bomb_position(vx,vy)
int vx,vy;
{
int num_bombs_around_goal;
/* find how many of the 3 squares around the goal has bombs */
num_bombs_around_goal =
(FIELD[NUMCOLS-1][NUMROWS-2].c==fc_bomb) +
(FIELD[NUMCOLS-2][NUMROWS-2].c==fc_bomb) +
(FIELD[NUMCOLS-2][NUMROWS-1].c==fc_bomb);
/* check to see if 4 most top-left squares are free */
if (((vx==0) && (vy==0)) || ((vx==0) && (vy==1)) ||
((vx==1) && (vy==0)) || ((vx==1) && (vy==1)) ||
((vx==NUMCOLS-1) && (vy==NUMROWS-1)) ||
(FIELD[vx][vy].c==fc_bomb) ||
((((vx==NUMCOLS-1) && (vy=NUMROWS-2)) ||
((vx==NUMCOLS-2) && (vy=NUMROWS-2)) ||
((vx==NUMCOLS-2) && (vy=NUMROWS-1))) &&
(num_bombs_around_goal==2)))
return (TRUE);
else
return (FALSE);
}
/* blocked: returns a boolean indicating whether a continuous line of bombs */
/* from square vx,vy (where vx,vy is on top or right edge) to */
/* the bottom or left edge of the field. If so, then return */
/* TRUE, else return FALSE. As each */
int blocked(vx,vy)
int vx,vy;
{
/* marked as safe means that square has already been looked at */
if (FIELD[vx][vy].m == fm_safe)
return (FALSE); /* square has already been looked at */
else
FIELD[vx][vy].m = fm_safe;
/* else mark square as having */
/* been looked at */
if (FIELD[vx][vy].c != fc_bomb)
return (FALSE); /* square has no bomb; thus, */
/* no path through here */
else {
if ((vx==0) || (vy==NUMROWS-1))
return (TRUE); /* we have reached the bottom or */
/* left edge and found a bomb */
if ((vy>0) && (FIELD[vx][vy-1].m==fm_nomark) &&
(blocked(vx,vy-1)))
return (TRUE);
if ((vy<NUMROWS-1) && (FIELD[vx][vy+1].m==fm_nomark) &&
(blocked(vx,vy+1)))
return (TRUE);
if ((vx>0) && (FIELD[vx-1][vy].m==fm_nomark) &&
(blocked(vx-1,vy)))
return (TRUE);
if ((vx<NUMCOLS-1) && (FIELD[vx+1][vy].m==fm_nomark) &&
(blocked(vx+1,vy)))
return (TRUE);
/* if we got this far, then there are no path of bombs */
/* through this square; thus, return not blocked */
return (FALSE);
} /* else FIELD[vx][vy] == fc_bomb */
}
/* guaranteed_path: returns a boolean indicating whether there is a path */
/* through the from start to goal without using grenades */
/* all field contents must be set first */
/* all field marks must be cleared first */
int guaranteed_path()
{
int c,r; /* current column and row being considered */
for (c=1;c<NUMCOLS;c++) /* c=1, skip starting square */
if (blocked(c,0))
return (FALSE); /* no path from start to finish */
for (r=0;r<NUMROWS-1;r++) /* NUMROWS-1, skip goal square */
if (blocked(NUMCOLS-1,r))
return (FALSE); /* no path from start to finish */
return (TRUE); /* else there is a guaranteed path */
}
/* manvx, manvy: current virtual man position on field */
int manvx,manvy;
/* set_field: will put the appropriate number of bombs in field */
/* according to level (makes sure that no illegal */
/* squares have bombs */
/* places man in top-left corner */
/* places goal in bottom-right corner */
/* guarantees that there is a path from start to end */
/* by repeating until that is true */
void set_field()
{
int c,r, /* column and row for clearing field */
i; /* counter for number of bombs */
/* placed so far */
int vx,vy; /* current bomb position being considered */
do {
/* first clear the entire field of all contents and marks */
for (c=0;c<NUMCOLS;c++)
for (r=0;r<NUMROWS;r++) {
FIELD[c][r].c = fc_empty; /* clear contents */
FIELD[c][r].m = fm_nomark; /* clear marks */
clear(c,r); /* erase bitmaps */
}
/* put man in top-left corner */
FIELD[0][0].c = fc_man;
manvx = 0; manvy = 0;
/* place bombs in field */
for (i=0;i<num_bombs_at_start[level];i++) {
do {
vx = random()%NUMCOLS;
vy = random()%NUMROWS;
} while (illegal_bomb_position(vx,vy));
FIELD[vx][vy].c = fc_bomb;
}
/* place goal in bottom-right corner */
FIELD[NUMCOLS-1][NUMROWS-1].c = fc_goal;
} while (!guaranteed_path());
/* now clear all marks from field */
for (c=0;c<NUMCOLS;c++)
for (r=0;r<NUMROWS;r++)
FIELD[c][r].m = fm_nomark; /* clear marks */
}